Velocity Reviews > Ruby > [Nuby Question] Return value of while loop.

[Nuby Question] Return value of while loop.

Brian Schröder
Guest
Posts: n/a

 09-18-2004
Maybe this question would be more adequate for the ruby-nuby forum , but
while I'm writing my lecture slides about ruby, I saw that a while loop
always returns nil. Eg.

i = 1 # => 0
i *= 2 while i > 100 # => nil

I would have expected the loop to return 128. Is there an intention behind
this? Just thought I'd voice my "least surprise" to see if for others this
is also against the POTS.

PS: If you want you can see this as a warmup for our first Quiz . What
is the most concise way to write this:

i = 1
loop do
i *= 2
break i if i > 100
end

which would simulate the behaviour I'd expect of the 2-liner above. (No
semicolons allowed)

Brian Schröder
Guest
Posts: n/a

 09-18-2004

> i = 1 # => 0
> i *= 2 while i > 100 # => nil

That was a typo, should have been
i = 1 # => 0
i *= 2 while i < 100 # => nil

cheers,

Brian

Kristof Bastiaensen
Guest
Posts: n/a

 09-18-2004
On Sat, 18 Sep 2004 10:43:18 +0200, Brian Schröder wrote:

> Maybe this question would be more adequate for the ruby-nuby forum , but
> while I'm writing my lecture slides about ruby, I saw that a while loop
> always returns nil. Eg.
>
> i = 1 # => 0
> i *= 2 while i > 100 # => nil
>
> I would have expected the loop to return 128. Is there an intention behind
> this? Just thought I'd voice my "least surprise" to see if for others this
> is also against the POTS.
>

Here is my guess:
I would suspect while to return the last statement. The last statement
will always be the test from the while, and always false. In this case
it may be more logical to return nil.

However it may be more useful if while returned the last value of the
block.

> PS: If you want you can see this as a warmup for our first Quiz . What
> is the most concise way to write this:
>
> i = 1
> loop do
> i *= 2
> break i if i > 100
> end
>
> which would simulate the behaviour I'd expect of the 2-liner above. (No
> semicolons allowed)

Here is a oneliner:
i = 128

Regards,
KB

Olivier D.
Guest
Posts: n/a

 09-18-2004
On 2004-09-18, Kristof Bastiaensen <(E-Mail Removed)> wrote:
>> PS: If you want you can see this as a warmup for our first Quiz . What
>> is the most concise way to write this:
>>
>> i = 1
>> loop do
>> i *= 2
>> break i if i > 100
>> end

>
> Here is a oneliner:
> i = 128

I can do better in two different ways:

\$i <<= 1 while defined?(\$i) ? (\$i < 100) : (\$i = 1)

or worse, my entry for a future Ruby's obfuscated code contest:
i = (i ? i : 1) * 2 while defined?(i) ? ((i ? i : 1) < 100) : (i = 1)

But there is a strange behaviour I don't understand, if I try:
i <<= 1 while defined?(i) ? (i < 100) : (i = 1)
the variable i is 'defined' but set to nil, that's why the previous line
won't work as expected...

--
Olivier D.

ts
Guest
Posts: n/a

 09-18-2004
>>>>> "O" == Olivier D <purple.dot_meteor@gmail_dot.com> writes:

O> i <<= 1 while defined?(i) ? (i < 100) : (i = 1)

i <<= 1 while i.nil?? (i = 1)i < 100)

Guy Decoux

Markus
Guest
Posts: n/a

 09-18-2004
On Sat, 2004-09-18 at 08:36, ts wrote:
> >>>>> "O" == Olivier D <purple.dot_meteor@gmail_dot.com> writes:

>
> O> i <<= 1 while defined?(i) ? (i < 100) : (i = 1)
>
> i <<= 1 while i.nil?? (i = 1)i < 100)

i <<= 1 while (i = i||1) < 100

-- MarkusQ

Brian Candler
Guest
Posts: n/a

 09-18-2004
On Sat, Sep 18, 2004 at 05:44:44PM +0900, Brian Schrder wrote:
> PS: If you want you can see this as a warmup for our first Quiz . What
> is the most concise way to write this:
>
> i = 1
> loop do
> i *= 2
> break i if i > 100
> end
>
> which would simulate the behaviour I'd expect of the 2-liner above. (No
> semicolons allowed)

I can do that in 5 characters plus a newline:

i=128

Perhaps you should reword your question as:

# x is initialised to an Integer
i = 1
loop do
i *= 2
break i if i > x
end

in which case the smallest I can think of is:

i=1
i*=2 while i<=x
i

(the third line being necessary since you want the answer to be the value of
the overall expression, not just being left in 'i')

Regards,

Brian.

Andrew Johnson
Guest
Posts: n/a

 09-18-2004
On Sun, 19 Sep 2004 01:25:07 +0900, Markus <(E-Mail Removed)> wrote:
> On Sat, 2004-09-18 at 08:36, ts wrote:
>> >>>>> "O" == Olivier D <purple.dot_meteor@gmail_dot.com> writes:

>>
>> O> i <<= 1 while defined?(i) ? (i < 100) : (i = 1)
>>
>> i <<= 1 while i.nil?? (i = 1)i < 100)

>
> i <<= 1 while (i = i||1) < 100

i *= 2 while (i = i||1) < 100

However, if I read the OP correctly, the interest wasn't the
shortest expression that sets i to 128 via doubling --- the
interest was in the shortest expression that "returned" the value of
i thusly set (sans semi-colons). The original example of what the
OP was after (in irb):

:~\$ irb
irb(main):001:0> i = 1
=> 1
irb(main):002:0> loop do
irb(main):003:1* i *= 2
irb(main):004:1> break i if i > 100
irb(main):005:1> end
=> 128

My first thought used the ability (for good or evil) to combine
if/while modifiers:

:~\$ irb
irb(main):001:0> i = 1
=> 1
irb(main):002:0> break i if i > 100 while i = i || 1 and i *= 2
=> 128

But a little rearranging results in a one liner:

:~\$ irb
irb(main):001:0> (i *= 2) > 100 and break i while i = i || 1
=> 128

regards,
andrew

--
Andrew L. Johnson http://www.siaris.net/
They're not soaking, they're rusting!
-- my wife (on my dishwashing habits)

Brian Candler
Guest
Posts: n/a

 09-18-2004
On Sat, Sep 18, 2004 at 05:32:02PM +0100, Brian Candler wrote:
> Perhaps you should reword your question as:
>
> # x is initialised to an Integer
> i = 1
> loop do
> i *= 2
> break i if i > x
> end
>
> in which case the smallest I can think of is:
>
> i=1
> i*=2 while i<=x
> i

Ah, I forgot ||= to initialise, so if you're counting lines rather than
characters:

i*=2 while (i||=1)<=x
i

Of course, i<<=1 might be microscopically faster. But it's also one
character longer

Brian.

Brian Schröder
Guest
Posts: n/a

 09-18-2004
> :~\$ irb
> irb(main):001:0> (i *= 2) > 100 and break i while i = i || 1
> => 128

You won, and I'm even able to grasp what you have written. So no
extra points for obfuscation

Cheers,

Brian