question on if / defined?()

J

Jedrin

assuming x is not defined, why does the statement

x = true if !defined?(x)


produce x is nil ?

y = true if !defined?(x)

is no different

this however works fine:

if !defined?(x)
x = true
end
 
R

Rick DeNatale

assuming x is not defined, why does the statement

x =3D true if !defined?(x)


produce x is nil ?

Because x is defined, this happens at parse time so it doesn't matter
if the assignment is executed or not.
y =3D true if !defined?(x)

=A0is no different

Not by itself

y =3D true if !defined? x

y # =3D> true

I'm guessing you had this in a program AFTER something which defined x
this however works fine:

if !defined?(x)
because at this point x is NOT defined since the parser hasn't yet seen it.
=A0x =3D true
end

HTH


--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 
J

John Sikora

Rick said:
I'm guessing you had this in a program AFTER something which defined x

The two statements were probably typed sequentioally. Consider the
outputs of two different irb sessions:

irb(main):001:0> y = true if !defined?(x)
=> true
irb(main):002:0> y
=> true
irb(main):003:0>

and

irb(main):001:0> x = true if !defined?(x)
=> nil
irb(main):002:0> x
=> nil
irb(main):003:0> y = true if !defined?(x)
=> nil
irb(main):004:0> y
=> nil
irb(main):005:0> x
=> nil
irb(main):006:0>

x was defined as nil.

js
 
J

John Sikora

Rick said:
Because x is defined, this happens at parse time so it doesn't matter
if the assignment is executed or not.

Is this because when the parser sees 'x = ...', Ruby automatically
assigns a reference to the variable x?

It seems to me that this is the only way that this behavior makes sense.

js
 
C

Colin Bartlett

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

Is this because when the parser sees 'x = ...', Ruby automatically
assigns a reference to the variable x?

I think that's correct, but I'd welcome confirmation from those more
knowledgeable about this.

irb
x
#=> NameError: undefined local variable or method 'x' for main:Object
x = x
#=> nil

Sort of assigning itself by it's own bootstraps?
 
B

Brian Candler

Here's a simpler example:

if false
x = 123
end
puts x # nil

x is defined, and has value nil. What has happened?

When the code is *parsed* (before it is executed at all, just when Ruby
is building an in-memory representation of the program), if Ruby sees an
assignment like x = ... then it marks x as being a local variable,
reserving a slot for it on the stack.

Whether the assignment is actually executed later or not is irrelevant.
From this point onwards to the end of the current scope, x is defined,
and is a local variable.

Why does ruby do this? There is a local variable / method call
ambiguity. Because you don't declare variables in Ruby, and because a
method call doesn't need parentheses after it, a bare "x" could be
either retrieving the value of x, or it could be calling the method x
with no arguments.

This simple parse-time algorithm decides in advance which you meant,
without you having to declare it.

puts x # undefined local variable or method `x'

def x
"Method x"
end
puts x # Method x

x = 123
puts x # 123

At this point it's decided that 'x' is a local variable, although you
can still force a method call instead:

puts x # 123
puts self.x # Method x
puts x() # Method x
 

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
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top