local vars clobbered by un-run code

T

Trans

Err...

irb(main):001:0> def x; 1; end
=> nil
irb(main):002:0> p x
1
=> nil
irb(main):003:0> if false
irb(main):004:1> x = x() + 1
irb(main):005:1> end
=> nil
irb(main):006:0> x
=> nil

Don't tell me, it's some quirk of the way Ruby works. Sure looks like
a bug though. Just in case:

ruby 1.8.4 (2005-12-24) [i486-linux]

Hmm... I just got a dejavu. Maybe I came across this before.

T.
 
T

Trans

Hi,

It's not a bug. Assignments makes identifiers local variables,
statically.

matz.

This must be the matz-bot. The answer came instantaneously and, deja-
vu again, I think it's same one I got before ;)

Thanks matz,
T.
 
R

Robert Dober

This must be the matz-bot. The answer came instantaneously and, deja-
vu again, I think it's same one I got before ;)
Let us see?

Which assignment Matz?

irb(main):001:0> def x;1 end
=> nil
irb(main):002:0> if false then
irb(main):003:1* def x; 2 end
irb(main):004:1> end
=> nil
irb(main):005:0> x
=> 1
irb(main):006:0> def y; 1 end
=> nil
irb(main):007:0> if false
irb(main):008:1> undef y
irb(main):009:1> end
=> nil
irb(main):010:0> y
=> 1

Surely the statements inside if are not executed.

Cheers
Robert
 
T

tsela.cg

Let us see?

Which assignment Matz?

irb(main):001:0> def x;1 end
=> nil
irb(main):002:0> if false then
irb(main):003:1* def x; 2 end
irb(main):004:1> end
=> nil
irb(main):005:0> x
=> 1
irb(main):006:0> def y; 1 end
=> nil
irb(main):007:0> if false
irb(main):008:1> undef y
irb(main):009:1> end
=> nil
irb(main):010:0> y
=> 1

Surely the statements inside if are not executed.

No, but they are parsed. And identifiers are made local variables at
parse time, not at execution time. So if you have an assignment
anywhere, even in a place that will never actually execute, the
identifier used in the assignment will be considered a local variable
by the interpreter.

Christophe.
 
R

Robert Dober

No, but they are parsed. And identifiers are made local variables at
parse time, not at execution time. So if you have an assignment
anywhere, even in a place that will never actually execute, the
identifier used in the assignment will be considered a local variable
by the interpreter.

Christophe.

I guess this can be concluded by what is happening, but is this any
reason to accept this behavior? I honestly do not feel so!

Cheers
Robert
 
T

Trans

I guess this can be concluded by what is happening, but is this any
reason to accept this behavior? I honestly do not feel so!

I do not feel so either. But, I've also learned that Ruby just has
some quirks. Matz wouldn't had done it this way unless there was a
very real need to do so. Now, that's not to say he might not have
missed a better solution, so it's still worth discussing if anyone has
one.

T.
 
I

Ian Whitlock

Trans said:
Don't tell me, it's some quirk of the way Ruby works. Sure looks like
a bug though. Just in case:

ruby 1.8.4 (2005-12-24) [i486-linux]

Hmm... I just got a dejavu. Maybe I came across this before.

T.

T all you showed is that sometimes the programmer must be responsible
for knowing whether he wants to reference a function or a variable.

Consider:

def x
1
end

p x #recognize function call without parens

if false
x = x() + 1 #variable x is created when code parsed
end

p x #reference the variable x which is nil because no assignment was
made
p x() #if the above were the function, how would you reference the
variable?

Result:

1
nil
1

Ian
 
R

Robert Dober

Trans wrote:
Tom it just strikes me, your thread and mine about Singleton classes
not being in ancestors and small other things I always see the same
pattern. Rick's blog entry is another example, always the same
pattern, it is the pattern of imperfection which is the *only* thing
that slightly bothers me in Ruby:


Consistency.

Maybe, probably I am wrong, but I feel that when it comes to these
subtle things Ruby is lacking consistency.

There just seems no reason for some behavior and your example above is
a classical example. You ask yourself why and you cannot find an
answer.

And worst of all, you have to remember!!

Still a great, great language of course.

Robert
 
T

Trans

Trans said:
Don't tell me, it's some quirk of the way Ruby works. Sure looks like
a bug though. Just in case:
ruby 1.8.4 (2005-12-24) [i486-linux]
Hmm... I just got a dejavu. Maybe I came across this before.

T all you showed is that sometimes the programmer must be responsible
for knowing whether he wants to reference a function or a variable.

One of things I always liked about Ruby is the fact the local vars and
methods are, in a certain sens of the word, polymorphic. Where a
method is being called, I can easily change it to be a variable. I
don't have to go thru the code and remove ()s or vice versa.

def chip
"%s chip"
end

def good
chip = "forget the %s chip"
puts chip % "good"
end

So if you can do that, it would seem reasonable that one could do so
conditionally as well. I find it odd that x is being setup as a local
var before ever being assigned as such. That's quite declarative for a
language that tends to shuns such things.

T.
 
T

Trans

Tom it just strikes me, your thread and mine about Singleton classes
not being in ancestors and small other things I always see the same
pattern. Rick's blog entry is another example, always the same
pattern, it is the pattern of imperfection which is the *only* thing
that slightly bothers me in Ruby:

Consistency.

Maybe, probably I am wrong, but I feel that when it comes to these
subtle things Ruby is lacking consistency.

There just seems no reason for some behavior and your example above is
a classical example. You ask yourself why and you cannot find an
answer.

And worst of all, you have to remember!!

Still a great, great language of course.

That is true. Ruby does have some rough edges. Though I chalk much of
it up to the fact that convenience and flexibility often comes with a
price of a few quirks.

T.
 
D

Daniel Martin

Robert Dober said:
I guess this can be concluded by what is happening, but is this any
reason to accept this behavior? I honestly do not feel so!

On the other hand, I find the idea that the scoping and binding of
variables could change based on the particular code path followed at
run time a horribly non-intuitive concept, since I think of "variable
scope" as something as static as the code itself - that is, you should
only be able to screw with variable scoping by strange
meta-programming tricks.
 
M

Mariusz Pękala

--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On the other hand, I find the idea that the scoping and binding of
variables could change based on the particular code path followed at
run time a horribly non-intuitive concept, since I think of "variable
scope" as something as static as the code itself - that is, you should
only be able to screw with variable scoping by strange
meta-programming tricks.

Maybe I don't understand something, but the decision whether something
is a variable or is a method call is based not on the code executed
(which is hard to predict when reading the source) but on the code
parsed, which is pretty static.

def this_method( x )
p y # This 'y' will always be a method call.
# (even if you call this_method again)
if x
y =3D 1 # because of this line in the source code...
end
p y # ...this 'y' will always be a variable.
end # ..independent on the value of x

So, I would (IMHO) assume, that this is not bad-black-magic, but
good-and-understandable-white-magic aspect of ruby.

The confision may emerge when the block of code has many lines, hard to
grasp in one eye shot, but I have been taught that if you write a
function that is longer than half of your editor window you should
extract part of it into another function.
With short blocks it is harder to mistake a method for a variable.

P.S.:
If someone still does not like this magic behaviour, assume that it
saves you from writing:

def this_method( x )
p y
if x
#pragma set_as_variable(y) /* and if you forgot, you will get parse-error */
y =3D 1
end
p y
end

;-)

--=20
No virus found in this outgoing message.
Checked by 'grep -i virus $MESSAGE'
Trust me.

--rwEMma7ioTxnRzrJ
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7-ecc0.1.6 (GNU/Linux)

iD8DBQFGeSxrsnU0scoWZKARAgWGAKDHXJoSBXQiY6Bsv5GGsDaUjCf/BQCfUCd5
9stzUpzthKhT6KlcNcUxfVQ=
=xe2b
-----END PGP SIGNATURE-----

--rwEMma7ioTxnRzrJ--
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top