Return values of modifiers

M

Michel Demazure

This is logical, but no very useful :

irb(main):007:0> x = 10
=> 10
irb(main):008:0> x = x + 1 if false
=> nil
irb(main):009:0> x = x + 1 if true
=> 11

Idem, a while modifier always returns nil

irb(main):010:0> x += 1 while x < 15
=> nil

It would be nice to get the return value of the last instruction
*before* the test fails.

_md
 
R

Robert Klemme

2010/4/30 Michel Demazure said:
This is logical, but no very useful :

irb(main):007:0> x = 10
=> 10
irb(main):008:0> x = x + 1 if false
=> nil
irb(main):009:0> x = x + 1 if true
=> 11

Idem, a while modifier always returns nil

irb(main):010:0> x += 1 while x < 15
=> nil

It would be nice to get the return value of the last instruction
*before* the test fails.

Why? What use case is there that would require this or what code
would become (much) more elegant?

Note that the cost (in terms of memory) might be significant if the
expression before "while" returns a large volume of data on each
iteration. That's probably irrelevant for most cases but it may cause
a nasty memory issues in rare cases because every last value needs to
be kept for the duration of the next loop execution.

Kind regards

robert
 
M

Michel Demazure

Robert said:
Why? What use case is there that would require this or what code
would become (much) more elegant?
I was just cleaning a library and found two methods ending with
something like

ind += 1 while <some_test>
ind
end

and tried to get rid of the last line, quite ugly and looking
unnecessary. You're right : not *much* more elegant. But once you get
used to syntactic sugar, you'll ask for some more ... Remember Dijsktra
: "abuse of syntactic sugar gives cancer of the semi-colon".
_md
 
D

David A. Black

Hi --

I was just cleaning a library and found two methods ending with
something like

ind += 1 while <some_test>
ind
end

and tried to get rid of the last line, quite ugly and looking
unnecessary. You're right : not *much* more elegant. But once you get
used to syntactic sugar, you'll ask for some more ... Remember Dijsktra
: "abuse of syntactic sugar gives cancer of the semi-colon".

I don't think there's any syntactic sugar here. I always think of
syntactic sugar as "It looks like it's doing X, but it's really [or
also] doing Y." For example, x * y, where it looks like an infix
operator but is really sending a message to an object.

In the case of the while in modifier position, it looks like it's
equivalent to this:

while <some_test>
ind += 1
end

and it is. I prefer this to having it be equivalent to:

loop do x += 1; break x if <some_test>; end


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

THE Ruby training with Black/Brown/McAnally
COMPLEAT Coming to Chicago area, June 18-19, 2010!
RUBYIST http://www.compleatrubyist.com
 
M

Michel Demazure

David said:
In the case of the while in modifier position, it looks like it's
equivalent to this:

while <some_test>
ind += 1
end

and it is. I prefer this to having it be equivalent to:

loop do x += 1; break x if <some_test>; end


David
Yes, that was my point.
_md
 
D

David A. Black

Hi --

Yes, that was my point.

I thought you were saying you *did* want it to be equivalent to that
loop construct, rather than to the non-modifier while construct. Did I
misunderstand?


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

THE Ruby training with Black/Brown/McAnally
COMPLEAT Coming to Chicago area, June 18-19, 2010!
RUBYIST http://www.compleatrubyist.com
 
M

Michel Demazure

Yes, that was my point.
_md
@David : Sorry, I misunderstood you, English is not my native tongue. I
read the opposite "I prefer it to be equivalent ...
_md
 
M

Michel Demazure

David said:
Hi --



I thought you were saying you *did* want it to be equivalent to that
loop construct, rather than to the non-modifier while construct. Did I
misunderstand?
No, you did not. This is was I suggested. But I misunderstood your first
comment, guessing you agreed with me. Sorry for the noise.
_md
 
B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

Sure, it would be nice while/until loops return value of the last iteration,
I agree.
 
M

Michel Demazure

Benoit said:
Sure, it would be nice while/until loops return value of the last
iteration,
I agree.

This boils down to the fact that 'if false ; end' returns nil, hence
means 'do nil' and not 'do nothing' (as a comment does).

Inserting a piece of code between 'if false' and 'end' is not equivalent
to commenting it out, and does not means 'jump over it'. I feel it
should.
 
R

Robert Dober

Benoit Daloze wrote:
Inserting a piece of code between 'if false' and 'end' is not equivalent
to commenting it out, and does not means 'jump over it'. I feel it
should.
The parser parses it, that is all, it is never executed I fail to see
what your desired behavior is?
Cheers
R.
 
M

Michel Demazure

I would like the return value of à block 'if <false> ; ... ; end' to be
the last return value before parsing the 'if'. As if the block did not
exist, or was commented out.
 
M

Michel Demazure

Michel said:
I would like the return value of a block 'if <false> ; ... ; end' to be
the last return value before parsing the 'if'. As if the block did not
exist, or was commented out.

I am not familiar with the ruby parser. What I suggest could be just to
pop the stack when exiting from the block.
_md
 
S

Seebs

I would like the return value of à block 'if <false> ; ... ; end' to be
the last return value before parsing the 'if'. As if the block did not
exist, or was commented out.

That would seem very surprising to me. In general, I do not expect the
return value of an expression to be the return value of some other expression
which was in no way a part of it.

-s
 
R

Robert Dober

I am not familiar with the ruby parser. What I suggest could be just to
pop the stack when exiting from the block.
_md
It is impossible, how could the parser continue its work??
 
B

Benoit Daloze

What I meant is:
i = 0 => 0
while i < 10
i += 1
33
end
=> nil # should be 33

This is already the case for class Foo..end, and if/unless

It should be for the loops too (without explicit break).

And when the condition is wrong and then the "block" is never used,
then nil should be returned.

What do you think?
 
M

Michel Demazure

Benoit said:
What I meant is:

=> nil # should be 33

This is already the case for class Foo..end, and if/unless

It should be for the loops too (without explicit break).

And when the condition is wrong and then the "block" is never used,
then nil should be returned.

What do you think?

Benoit, if you have only
i = 0
while i < 10
i += 1
end
which is the same as
i = 0
while i < 10
i += 1
i
end
then it should return 10, as I wanted ?
_md
 
B

Benoit Daloze

2010/5/1 Michel Demazure said:
Benoit, if you have only
=A0i =3D 0
=A0while i < 10
=A0 i +=3D 1
=A0end
which is the same as
=A0i =3D 0
=A0while i < 10
=A0 i +=3D 1
=A0 i
=A0end
then it should return 10, as I wanted ?
_md

Sure, that's my point.

(But I think the 'if/unless' behavior is correct and "foo if false"
should return nil as it is)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top