我到处都看到这个片段,它有效!为什么呢?
while gets
print if /start/../end/
end
如果没有Lvalue,ruby如何评估/start/
?我希望我们首先必须在某处存储'gets'的值,然后再进行
gets_result =~ /start/.. gets_result =~ /end/
那么为什么代码片段有效?
让我澄清一下。
ruby如何知道比较正则表达式与获取在上面的代码段中,我没有指定ruby将reg exp与gets
进行比较但它只是知道。问题是怎么样的?
答案 0 :(得分:4)
答案 1 :(得分:2)
好问题。
请记住:在条件语句中使用Range
运算符(..
或...
)时,它会执行某些操作完全出乎意料:它没有创建一个Range
对象。相反,它充当“触发器”运算符。
下面的代码实际上是
while gets
print if /start/../end/
end
默认为
while gets
# gets_input I put just to make the code more expressive
# actually the input taken using gets method applied here implicitly.
print if /start/ =~ gets_input .. /end/ =~ gets_input
end
让我来证明你。我接受了Ruby Tracer
类的帮助。
trace = TracePoint.new do |tp|
p [tp.lineno, tp.event, tp.defined_class,tp.method_id]
end
trace.enable do
while gets
# when you type start in your console, 11 will be output.
print 11 if /start/../end/
end
end
让我运行此代码,向您展示我的上述代码作为证明以及Ruby Flip-Flop 功能:
(arup~>Ruby)$ ruby test.rb
test.rb:6: warning: regex literal in condition
test.rb:6: warning: regex literal in condition
[4, :b_call, nil, nil]
[5, :line, nil, nil]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
end # I presses **end** here.
[5, :c_return, ARGF.class, :gets]
[5, :c_return, Kernel, :gets]
[6, :line, nil, nil]
# Regexp#=~ call begin happened for /end/ =~ gets_input
[6, :c_call, Regexp, :=~]
# Regexp#=~ call end happened for /end/ =~ gets_input
[6, :c_return, Regexp, :=~]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
start # I presses **start** here.
[5, :c_return, ARGF.class, :gets]
[5, :c_return, Kernel, :gets]
[6, :line, nil, nil]
# Regexp#=~ call begin happened for /start/ =~ gets_input
[6, :c_call, Regexp, :=~]
# Regexp#=~ call end happened for /start/ =~ gets_input
[6, :c_return, Regexp, :=~]
# Regexp#=~ call begin happened for /end/ =~ gets_input
[6, :c_call, Regexp, :=~]
# Regexp#=~ call end happened for /end/ =~ gets_input
[6, :c_return, Regexp, :=~]
[6, :c_call, Kernel, :print]
[6, :c_call, IO, :write]
[6, :c_call, Fixnum, :to_s]
[6, :c_return, Fixnum, :to_s]
# As there is a match so **if** clause true, thus 11 printed
11[6, :c_return, IO, :write]
[6, :c_return, Kernel, :print]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
end
[5, :c_return, ARGF.class, :gets]
[5, :c_return, Kernel, :gets]
[6, :line, nil, nil]
[6, :c_call, Regexp, :=~]
[6, :c_return, Regexp, :=~]
[6, :c_call, Kernel, :print]
[6, :c_call, IO, :write]
[6, :c_call, Fixnum, :to_s]
[6, :c_return, Fixnum, :to_s]
11[6, :c_return, IO, :write]
[6, :c_return, Kernel, :print]
[5, :c_call, Kernel, :gets]
[5, :c_call, ARGF.class, :gets]
答案 2 :(得分:0)
在这种情况下,..
是触发器操作符。给定'start'时,条件的计算结果为true,并继续true
直到end
为止。