что означает этот обратный код рубина? - PullRequest
2 голосов
/ 07 декабря 2009
while line = gets
   next if line =~ /^\s*#/    # skip comments
   break if line =~ /^END/   # stop at end

   #substitute stuff in backticks and try again
   redo if line.gsub!(/`(.*?)`/) { eval($1) } 

конец

Чего я не понимаю, так это строки:

line.gsub!(/`(.*?)`/) { eval($1) }
  1. Что значит гсуб! точно делать?
  2. значение регулярного выражения (. *?)
  3. значение блока {eval ($ 1)}

Ответы [ 3 ]

5 голосов
/ 07 декабря 2009
  1. Он заменит в согласованной части line результат блока.
  2. Он будет соответствовать 0 или более из предыдущего подвыражения (которое было '.', Соответствует любому одному символу). ? изменяет .* RE так, чтобы оно соответствовало не более, чем необходимо для продолжения сопоставления последующих элементов RE. Это называется "не жадный". Без ?, .* может также соответствовать второму обратному трюку, в зависимости от остальной части строки, и тогда выражение в целом может потерпеть неудачу.
  3. Блок возвращает результат eval («вычислить выражение Ruby») по обратной ссылке, которая является частью строки между символами обратной галочки. Это определяется $1, что относится к первому заключенному в скобки разделу («обратная ссылка») RE.

В целом, результатом всего этого является то, что в строках, содержащих выражения, заключенные в квадратные скобки, часть внутри обратных галочек (и обратных черт) заменяется значением результата выполнения содержащегося в нем выражения Ruby. А поскольку внешний блок подчиняется redo, цикл будет немедленно повторяться без повторного выполнения условия while. Это означает, что полученное выражение также подлежит обратному анализу.

3 голосов
/ 07 декабря 2009

Заменяет все, что находится между обратными галочками в line, в результате оценки содержащегося в нем рубинового кода.

>> line = "one plus two equals `1+2`"
>> line.gsub!(/`(.*?)`/) { eval($1) }
>> p line
=> "one plus two equals 3"

.* соответствует нулю или нескольким символам, ? делает его нежадным (т. Е. Оно будет принимать самое короткое совпадение, а не самое длинное).

$1 - строка, которая соответствует материалу между (). В приведенном выше примере $1 было бы установлено на "1+2". eval оценивает строку как код ruby.

1 голос
/ 07 декабря 2009

line.gsub!(/ (. *?) /) { eval($1) }

  1. GSUB! заменяет строку (вместо этого при использовании line = line.gsub).
  2. . *? поэтому он будет соответствовать только до первого `, иначе он заменит несколько совпадений.
  3. Блок выполняет все, что ему соответствует (например, если «строка» содержит 1+1, eval заменит его на 2.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...