From: Ken Bloom Date: 2009-10-07T21:08:37+09:00 Subject: Re: On Ranges as conditions On Sun, 04 Oct 2009 04:06:56 +0900, Rick DeNatale wrote: > On Sat, Oct 3, 2009 at 1:15 PM, Rafael Cunha de Almeida > wrote: >> Reading a few tutorials I found this piece of code: >> >>        while input = gets >>            input = input.chomp >>            puts input + " triggered" if input =~ /start/ .. input >>            =~ /end/ >>        end >> >> I understand what it does. If I type start, end or anything in between >> it prints >> "triggered" after the input. Now, if I'm out of the start .. end block, >> the if >> fails. >> >> What I don't understand is how it does it. For instance, if I use the >> interpreter to do something like this: >> >>        irb(main):038:0> input = 'fooo' >>        => "fooo" >>        irb(main):039:0> puts input + " triggered" if input =~ >>        /start/ .. input >> =~ /end/ >>        => nil >>        irb(main):040:0> input = 'start' >>        => "start" >>        irb(main):041:0> puts input + " triggered" if input =~ >>        /start/ .. input >> =~ /end/ >>        start triggered >>        => nil >>        irb(main):042:0> input = 'bar' >>        => "bar" >>        irb(main):043:0> puts input + " triggered" if input =~ >>        /start/ .. input >> =~ /end/ >>        => nil >> >> it doesn't work as I'd expect. I thought the if clause there would >> somehow set a >> global to say "the first regex was matched" or something like that. But >> it doesn't seem to be the way it works. It only seems to work inside of >> a while loop. I thought it might have something to do with the $_ >> global. But I made a >> test in the interpreter which ruled out that theory: >> >>        irb(main):045:0> $_ = 'foo' >>        => "foo" >>        irb(main):046:0> input = 'foo' >>        => "foo" >>        irb(main):047:0> puts input + " triggered" if input =~ >>        /start/ .. input >> =~ /end/ >>        => nil >>        irb(main):048:0> $_ = input = 'start' => "start" >>        irb(main):049:0> puts input + " triggered" if input =~ >>        /start/ .. input >> =~ /end/ >>        start triggered >>        => nil >>        irb(main):050:0> $_ = input = 'foo' >>        => "foo" >>        irb(main):051:0> puts input + " triggered" if input =~ >>        /start/ .. input >> =~ /end/ >>        => nil >>        irb(main):052:0> >> >> Can anyone help me find out what's going on? > > As far as I can tell, from reading the 1.8 parse.c code, the problem is > that conditional ranges really aren't Range instances but are really a > kind of syntactic sugar. Every time you retype the source line into > irb, you get an entirely new parse, and a new conditional range in the > initial state. Pretty cool! Thanks for pointing this syntax out! I don't recall seeing it in Pickaxe. One question: irb(main):013:0> a=%w{foo start bar end baz start foo bar end baz} => ["foo", "start", "bar", "end", "baz", "start", "foo", "bar", "end", "baz"] irb(main):014:0> a.each {|i| puts i + (if i =~ /start/ .. i =~ /end/ then " triggered" else "" end) } foo start triggered bar triggered end triggered baz start triggered foo triggered bar triggered end triggered baz => ["foo", "start", "bar", "end", "baz", "start", "foo", "bar", "end", "baz"] irb(main):015:0> a.each {|i| puts i + (if i =~ /start/ ... i =~ /end/ then " triggered" else "" end) } foo start triggered bar triggered end triggered baz start triggered foo triggered bar triggered end triggered baz Shouldn't the last version (using ... instead of ..) logically omit the end line from the triggered section? --Ken -- Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory. Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/