loses scope?

R

Roger Pack

Anybody know why this fails?

a = 32
class A
def go
a
end
end
puts A.new.go # raises with "a not defined"

?
Thanks.
-r
 
J

Jesús Gabriel y Galán

Anybody know why this fails?

a =3D 32
class A
=A0def go
=A0a
=A0end
end
puts A.new.go # raises with "a not defined"

?

Because both "class" and "def" keywords create a new scope. They are
not closures, they don't see their surrounding scope. Consider this
other way, which doesn't create new scopes:

irb(main):001:0> a =3D 3
=3D> 3
irb(main):008:0> Test =3D Class.new do
irb(main):009:1* define_method:)go) do
irb(main):010:2* puts a
irb(main):011:2> end
irb(main):012:1> end
=3D> Test
irb(main):013:0> Test.new.go
3
=3D> nil

Jesus.
 
J

Joel VanderWerf

Anybody know why this fails?

a = 32
class A
def go
a
end
end
puts A.new.go # raises with "a not defined"

You may want to call class_eval and define_method with blocks instead.
 
R

Roger Pack

Jesús Gabriel y Galán said:
Because both "class" and "def" keywords create a new scope. They are
not closures, they don't see their surrounding scope. Consider this
other way, which doesn't create new scopes:

That I did not know. Thanks!
-r
 
P

Philliam Auriemma

Ah thanks for posting that, I'm rather new to ruby and that was
confusing me.
 
R

Roger Pack

You may want to call class_eval and define_method with blocks instead.

Hmm. Perhaps an example using class_eval would help me understand that
better (define_method works great, BTW).
Thanks!
-r
 
J

Jesús Gabriel y Galán

Hmm. Perhaps an example using class_eval would help me understand that
better (define_method works great, BTW).
Thanks!

irb(main):001:0> class A
irb(main):002:1> end
=> nil
irb(main):005:0> a = 3
=> 3
irb(main):006:0> A.class_eval do
irb(main):007:1* define_method:)go) do
irb(main):008:2* puts a
irb(main):009:2> end
irb(main):010:1> end
=> #<Proc:0xb7dbffd0@(irb):7>
irb(main):011:0> A.new.go
3
=> nil

When you already have the class A created and you open it to add the
'go' method, you can use class_eval, which receives a block. Blocks
are closures, so they see their surrounding scope, and thus, the
variable 'a'.

Jesus.
 
J

Jeff Shantz

Jesús Gabriel y Galán said:
irb(main):001:0> class A
irb(main):002:1> end
=> nil
irb(main):005:0> a = 3
=> 3
irb(main):006:0> A.class_eval do
irb(main):007:1* define_method:)go) do
irb(main):008:2* puts a
irb(main):009:2> end
irb(main):010:1> end
=> #<Proc:0xb7dbffd0@(irb):7>
irb(main):011:0> A.new.go
3
=> nil

Just curious... is there any difference between using define_method and
def in this case? It seems they achieve the same effect. Why would one
be preferred over the other?
?> define_method:)test) do
?> puts "Testing!"Testing!
=> nilTesting!!
=> nil

Thanks.

Jeff
 
J

Jesús Gabriel y Galán

Just curious... is there any difference between using define_method and
def in this case? =A0It seems they achieve the same effect. =A0Why would = one
be preferred over the other?

?> =A0 =A0 define_method:)test) do
?> =A0 =A0 =A0 puts "Testing!"
Testing!
=3D> nil
Testing!!
=3D> nil

The difference is that def starts a new scope, it's not a closure, so
it doesn't see its surrounding scope. In the following case (as well
as the original case by the OP), the local variable 'a' is seen in the
block passed to define_method, but not to the body of the 'def'
keyword, since it's not a closure:

irb(main):001:0> class A; end
=3D> nil
irb(main):002:0> a =3D 3
=3D> 3
irb(main):003:0> A.class_eval do
irb(main):004:1* define_method:)go) do
irb(main):005:2* puts a # this a is the a outside the class_eval
irb(main):006:2> end
irb(main):007:1> end
=3D> #<Proc:0xb788d530@(irb):4>
irb(main):008:0> A.new.go
3
=3D> nil
irb(main):009:0> A.class_eval do
irb(main):010:1* def no_go
irb(main):011:2> puts a #this one is undefined
irb(main):012:2> end
irb(main):013:1> end
=3D> nil
irb(main):014:0> A.new.no_go
NameError: undefined local variable or method `a' for #<A:0xb7870584>
from (irb):11:in `no_go'
from (irb):14
from :0

Hope this helps,

Jesus.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,431
Latest member
ElyseG3173

Latest Threads

Top