Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > On Ranges as conditions

Reply
Thread Tools

On Ranges as conditions

 
 
Rafael Cunha de Almeida
Guest
Posts: n/a
 
      10-03-2009
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?
 
Reply With Quote
 
 
 
 
Rick DeNatale
Guest
Posts: n/a
 
      10-03-2009
On Sat, Oct 3, 2009 at 1:15 PM, Rafael Cunha de Almeida
<(E-Mail Removed)> wrote:
> Reading a few tutorials I found this piece of code:
>
> =A0 =A0 =A0 =A0while input =3D gets
> =A0 =A0 =A0 =A0 =A0 =A0input =3D input.chomp
> =A0 =A0 =A0 =A0 =A0 =A0puts input + " triggered" if input =3D~ /start/ ..=

input =3D~ /end/
> =A0 =A0 =A0 =A0end
>
> 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:
>
> =A0 =A0 =A0 =A0irb(main):038:0> input =3D 'fooo'
> =A0 =A0 =A0 =A0=3D> "fooo"
> =A0 =A0 =A0 =A0irb(main):039:0> puts input + " triggered" if input =3D~ /=

start/ .. input
> =3D~ /end/
> =A0 =A0 =A0 =A0=3D> nil
> =A0 =A0 =A0 =A0irb(main):040:0> input =3D 'start'
> =A0 =A0 =A0 =A0=3D> "start"
> =A0 =A0 =A0 =A0irb(main):041:0> puts input + " triggered" if input =3D~ /=

start/ .. input
> =3D~ /end/
> =A0 =A0 =A0 =A0start triggered
> =A0 =A0 =A0 =A0=3D> nil
> =A0 =A0 =A0 =A0irb(main):042:0> input =3D 'bar'
> =A0 =A0 =A0 =A0=3D> "bar"
> =A0 =A0 =A0 =A0irb(main):043:0> puts input + " triggered" if input =3D~ /=

start/ .. input
> =3D~ /end/
> =A0 =A0 =A0 =A0=3D> 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 i=

t
> doesn't seem to be the way it works. It only seems to work inside of a wh=

ile
> 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:
>
> =A0 =A0 =A0 =A0irb(main):045:0> $_ =3D 'foo'
> =A0 =A0 =A0 =A0=3D> "foo"
> =A0 =A0 =A0 =A0irb(main):046:0> input =3D 'foo'
> =A0 =A0 =A0 =A0=3D> "foo"
> =A0 =A0 =A0 =A0irb(main):047:0> puts input + " triggered" if input =3D~ /=

start/ .. input
> =3D~ /end/
> =A0 =A0 =A0 =A0=3D> nil
> =A0 =A0 =A0 =A0irb(main):048:0> $_ =3D input =3D 'start'
> =A0 =A0 =A0 =A0=3D> "start"
> =A0 =A0 =A0 =A0irb(main):049:0> puts input + " triggered" if input =3D~ /=

start/ .. input
> =3D~ /end/
> =A0 =A0 =A0 =A0start triggered
> =A0 =A0 =A0 =A0=3D> nil
> =A0 =A0 =A0 =A0irb(main):050:0> $_ =3D input =3D 'foo'
> =A0 =A0 =A0 =A0=3D> "foo"
> =A0 =A0 =A0 =A0irb(main):051:0> puts input + " triggered" if input =3D~ /=

start/ .. input
> =3D~ /end/
> =A0 =A0 =A0 =A0=3D> nil
> =A0 =A0 =A0 =A0irb(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.


--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/pers...-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

 
Reply With Quote
 
 
 
 
Markus Roberts
Guest
Posts: n/a
 
      10-03-2009
It isn't a range, it's a "flip-flop" which happens to use the same
operator ('..') as range construction.

While useful in some sed/awk like scripts it's not a widely used
feature.

-- MarkusQ

 
Reply With Quote
 
Josh Cheek
Guest
Posts: n/a
 
      10-03-2009
[Note: parts of this message were removed to make it a legal post.]

On Sat, Oct 3, 2009 at 12:15 PM, Rafael Cunha de Almeida
<(E-Mail Removed)>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?
>
>

# (this entire response can be directly placed into a script -- not the
above quote, though)
#
# The first condition turns it on (causes it to evaluate to true)
# the second turns it off (causes it to evaluate back to false).
# In this example, you would get the output
#
# start triggered
# instruction2 triggered
# instruction3 triggered
# end triggered
# start triggered
# instruction6 triggered
# instruction7 triggered
# instruction8 triggered
# end triggered
#
# Give it a try

$stdin = DATA

while input = gets
input = input.chomp
puts input + " triggered" if input =~ /start/ .. input =~ /end/
end

__END__
instruction0
instruction1
start
instruction2
instruction3
end
instruction4
instruction5
start
instruction6
instruction7
instruction8
end
instruction9

 
Reply With Quote
 
Xavier Noria
Guest
Posts: n/a
 
      10-04-2009
On Saturday, October 3, 2009, Markus Roberts <(E-Mail Removed)> wrote:
> It isn't a range, it's a "flip-flop" which happens to use the same operator ('..') as range construction.
>
> While useful in some sed/awk like scripts it's not a widely used feature.


Well, it is used as often as you find the problem it solves, no matter
the language.

 
Reply With Quote
 
Ken Bloom
Guest
Posts: n/a
 
      10-07-2009
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
> <(E-Mail Removed)> 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/


 
Reply With Quote
 
Colin Bartlett
Guest
Posts: n/a
 
      10-08-2009
On Wed, Oct 7, 2009 at 1:08 PM, Ken Bloom <(E-Mail Removed)> wrote:
> Pretty cool! Thanks for pointing this syntax out! I don't recall seeing
> it in Pickaxe.

It's definitely in the first (2001) edition as "Ranges as conditions":
_A range used in a boolean expression acts as a flip-flop.
_ It has two states, set and unset, and is initially unset.
_ On each call, the range cycles through the state machine ...
_ The range returns true if it is in the set state at the end of the call,
_ and false otherwise.
_The two-dot form of a range behaves slightly differently than the
three-dot form.
_ When the two-dot form first makes the transition from unset to set,
_it immediately evaluates the end condition and makes the transition
accordingly.
_This means that if expr1 and expr2 both evaluate to true on the same call,
_the two-dot form will finish the call in the unset state.
_However, it still returns true for this call.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ranges vs subnets Peter Lecki Cisco 7 01-17-2006 10:32 AM
another array ranges mystery valentin tihomirov VHDL 2 06-18-2005 05:53 PM
Multiple ISPs and Multiple IP Ranges from Each ISP Chennak Cisco 10 06-08-2005 09:29 PM
PIX-501 with multiple outside IP ranges Mike Ruskai Cisco 3 02-14-2005 11:43 PM
Cisco Playstation 2 Setup Comments, Ports forwarding Ranges Jim Saunders Cisco 0 03-05-2004 10:16 AM



Advertisments