'Оценка', как предполагается, противна?

Форматирование и стилизация

Да, см. следующее из Строковые ресурсы: форматирование и стилизация

Если вам нужно отформатировать строки, используя String.format(String, Object...), тогда вы можете сделать это, поместив аргументы формата в ресурс строки. Например, со следующим ресурсом:

Hello, %1$s! You have %2$d new messages.

В этом примере строка формата имеет два аргумента: %1$s - это строка, а %2$d - десятичное число. Вы можете отформатировать строку с аргументами из вашего приложения следующим образом:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
blockquote>

Основное использование

Обратите внимание, что getString имеет перегрузку, которая использует эту строку как format:

String text = res.getString(R.string.welcome_messages, username, mailCount);

Plurals

Если вам нужно обрабатывать множественные числа, используйте это:


    Hello, %1$s! You have a new message.
    Hello, %1$s! You have %2$d new messages.

Первый параметр mailCount используется для решить, какой формат использовать (одно или несколько), другими параметрами являются ваши подстановки:

Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);

Подробнее см. в String Resources: Plurals .

23
задан Chirantan 12 March 2009 в 04:55
поделиться

7 ответов

Если Вы eval луг строка, отправленная, или модифицируемые пользователем, это эквивалентно разрешению выполнения произвольного кода. Вообразите, содержала ли строка вызов ОС к rm -rf / или подобный. Тем не менее в ситуациях, где Вы знаете, строки соответственно ограничиваются, или Ваш интерпретатор Ruby поигрался в песочнице соответственно, или идеально оба, eval могут быть чрезвычайно мощными.

проблема походит Внедрение SQL , если Вы знакомы. Решение здесь аналогично решению инжекционной проблемы (параметризированные запросы). Таким образом, если операторы, которые Вы хотели бы к eval, как известно, имеют очень определенную форму, а не весь из оператора должны быть отправленным пользователем, только несколькими переменными, математическим выражением, или подобный, можно взять в этих маленьких частях от пользователя, санировать их при необходимости, затем оценить безопасный шаблонный оператор с вводом данных пользователем, включенным в соответствующих местах.

33
ответ дан Matt J 29 November 2019 в 00:56
поделиться

eval не только небезопасен (как уже указывалось в другом месте), он также медленный. Каждый раз, когда он выполняется, AST кода eval необходимо заново анализировать (и, например, для JRuby, превращенного в байт-код), что является строковой операцией и, вероятно, также плохо для локальности кэша (в предположении что работающей программы не много eval, и соответствующие части интерпретатора, таким образом, кешируются, помимо того, что они большие).

Почему в Ruby вообще есть eval, спросите вы? В основном «потому что мы можем» - фактически, когда было изобретено eval (для языка программирования LISP), это было в основном для шоу ! Более того, использование eval - это правильная вещь, когда вы хотите «добавить интерпретатор в ваш интерпретатор» для таких задач метапрограммирования, как написание препроцессора, отладчика или шаблонизатора. Общая идея для таких приложений состоит в том, чтобы помассировать некоторый код Ruby и вызвать eval для него, и это, безусловно, лучше, чем переосмысление и реализация предметно-ориентированного игрушечного языка, ловушка, также известная как Десятое правило Гринспуна . Предостережения: остерегайтесь затрат, например, для движка шаблонов, делайте все свои работы во время запуска, а не во время работы; и не eval не доверяйте коду, если вы не знаете, как его «приручить», то есть выберите и примените безопасное подмножество языка в соответствии с теорией дисциплины способностей . Последний - это много действительно трудной работы (см., Например, , как это было сделано для Java ; я не знаю о таких усилиях для Ruby, к сожалению).

10
ответ дан DomQ 29 November 2019 в 00:56
поделиться

В Ruby есть несколько уловок, которые могут быть более подходящими, чем eval():

  1. Существует #send, который позволяет вам вызывать метод, имя которого у вас есть в виде строки, и передавать параметры в она.
  2. yield позволяет передавать блок кода методу, который будет выполняться в контексте метода получения.
  3. Часто простого Kernel.const_get("String") достаточно, чтобы получить класс, имя которого у вас есть в виде строки.

Я думаю, что я не могу объяснить их должным образом подробно, поэтому я просто дал вам подсказки, если вы заинтересованы, вы будете Google.

11
ответ дан the Tin Man 29 November 2019 в 00:56
поделиться

Это затрудняет отладку. Это затрудняет оптимизацию. Но, прежде всего, обычно это признак того, что есть лучший способ сделать то, что вы пытаетесь сделать.

Если вы расскажете нам, чего вы пытаетесь достичь с помощью eval, вы можете получить более релевантные ответы, относящиеся к вашему конкретному сценарию.

7
ответ дан recursive 29 November 2019 в 00:56
поделиться

Оценка является невероятно мощной функцией, которая должна быть использована тщательно. Помимо проблем безопасности, на которые указывает Матовый J, Вы также найдете, что отладка оцененного кода времени выполнения является чрезвычайно трудной. Проблема в оцененном блоке кода времени выполнения будет трудной для интерпретатора выразить - настолько ищущий, это будет трудно.

Однако если Вы довольны той проблемой и не обеспокоены проблемой безопасности, тогда Вы не должны избегать использования одной из функций, которая делает рубин как обращающийся как есть

6
ответ дан 29 November 2019 в 00:56
поделиться

В определенных ситуациях удачное расположение eval является умным и уменьшает количество требуемого кода. В дополнение к проблемам безопасности, которые были упомянуты Мэттом J, вам также нужно задать себе один очень простой вопрос:

Когда все это сказано и сделано, может ли кто-нибудь еще прочесть ваш код и понять, что вы сделали?

Если ответ отрицательный, то то, что вы получили с eval, забывается для удобства обслуживания. Эта проблема не только применима, если вы работаете в команде, но также применима и к вам - вы хотите иметь возможность оглянуться назад на свои месяцы кода, если не годы, и знать, что вы сделали.

5
ответ дан the Tin Man 29 November 2019 в 00:56
поделиться

Если вы передаете что-либо, что вы получаете «извне», eval, вы делаете что-то не так, и это очень неприятно. очень трудно избежать кода, достаточного для того, чтобы он был безопасным, поэтому я считаю его довольно небезопасным. Тем не менее, если вы используете eval для избежания дублирования или других подобных вещей, как в следующем примере кода, можно использовать его.

class Foo
  def self.define_getters(*symbols)
    symbols.each do |symbol|
      eval "def #{symbol}; @#{symbol}; end"
    end
  end

  define_getters :foo, :bar, :baz
end

Однако, по крайней мере в Ruby 1.9.1, в Ruby есть действительно мощные методы метапрограммирования, и вы могли бы вместо этого сделать следующее:

class Foo
  def self.define_getters(*symbols)
    symbols.each do |symbol|
      define_method(symbol) { instance_variable_get(symbol) }
    end
  end

  define_getters :foo, :bar, :baz
end

Для большинства целей вы хотите использовать эти методы, и не нужно убегать.

Другая плохая вещь в eval заключается в том, что (по крайней мере, в Ruby) он довольно медленный, поскольку интерпретатору необходимо проанализировать строку и затем выполнить код внутри текущей привязки. Другие методы вызывают функцию C напрямую, и поэтому вы должны получить значительное ускорение.

-1
ответ дан sarahhodne 29 November 2019 в 00:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: