2009-12-07 103 views
2
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. 什么的GSUB!准确地做?
  2. 正则表达式的含义(。*?)
  3. 块{的eval($ 1)}

回答

5
  1. 它将的line匹配部分内的替代品,该块的结果的意思。
  2. 它将匹配前面的子表达式(即'。',匹配任何一个字符)中的0个或更多个。 ?修改.* RE,以便匹配不超过继续匹配后续RE元素所需的数量。这被称为“非贪婪”。如果没有?,则.*也可能与第二个反引号匹配,具体取决于该行的其余部分,然后整个表达式可能会失败。
  3. 的块返回的eval的结果(“评估红宝石表达”)上反向引用,这是背面蜱字符之间的字符串的一部分。这由$1指定,它指RE的第一个非封闭部分(“反向引用”)。

大体而言,所有这些结果都是包含反引号括起来的表达式的行将反引号内的部分(和反引号)替换为执行包含的Ruby表达式的结果值。并且由于外部块受到redo的限制,所以循环将立即重复,而不会重新运行while条件。这意味着结果表达式也会受到反向评估。

1

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

  1. GSUB!替换行(而不是如果使用line = line.gsub)。
  2. 。*?所以它只会匹配到第一个`,否则它会替换多个匹配。
  3. 块执行任何它匹配(因此,例如,如果“线”包含1+1,EVAL将与2
3
替换

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代码。