def foo(x)
def bar(n)
n + 1
end
bar(x)
end
foo(5) # -> 6
bar(5) # -> 6
Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?
Charlie
def foo(x)
def bar(n)
n + 1
end
bar(x)
end
foo(5) # -> 6
bar(5) # -> 6
Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?
Charlie
Hi,
At Wed, 3 Mar 2004 15:44:46 +0900,
Charles Comstock wrote in [ruby-talk:94119]:
Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?
Current inner method just keeps undefined until the outer
method executes, but has no lexical scope at all.
–
Nobu Nakada
def foo(x)
def bar(n)
n + 1
end
bar(x)
end
foo(5) # ->> 6
bar(5) # ->> 6
Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?
Heh, I thought “def inside def” wasn’t even allowed!
Gavin
On Wednesday, March 3, 2004, 5:44:46 PM, Charles wrote:
Intended feature
Method definitions are scoped the same way as @variables; the new
method is added to the current instance. It doesn’t matter if you do it
at the “base level” of the class, or if you stick it ten layers down
inside blocks of code, it still gets added to the instance.
class Foo
def bar
def quux
"quux!"
end
"defined quux..."
end
end
==>nil
f=Foo.new
==>#<Foo:0x63300>
f.methods - Object.new.methods
==>["bar"]
f.quux
NoMethodError: undefined method `quux' for #<Foo:0x63300>
from (irb):11
f.bar
==>"defined quux..."
f.quux
==>"quux!"
f.methods - Object.new.methods
==>["bar", "quux"]
–Mark
On Mar 2, 2004, at 10:44 PM, Charles Comstock wrote:
def foo(x)
def bar(n)
n + 1
end
bar(x)
endfoo(5) # → 6
bar(5) # → 6Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?
Probably quite intentional; I quite often use it for dynamic
(re)definition of methods and would be annoyed if it went away…
I suggest if you need this behaviour, use a proc literal assigned to a
local variable, thus:
def foo(x)
bar = proc do |n|
n + 1
end
bar.call(x) # or bar
end
foo(5) # → 6
bar(5) # → wtf? I don’t know what bar is.
Tim.
nobu.nokada@softhome.net wrote:
At Wed, 3 Mar 2004 15:44:46 +0900,
Charles Comstock wrote in [ruby-talk:94119]:Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?
–
Tim Bates
tim@bates.id.au
Mark Hubbart wrote:
def foo(x)
def bar(n)
n + 1
end
bar(x)
endfoo(5) # → 6
bar(5) # → 6Why is bar escaping the scope of foo? Is this a bug, or an unintended
feature?Intended feature
Method definitions are scoped the same way as @variables; the new method
is added to the current instance. It doesn’t matter if you do it at the
^^^^^^^^
Not exactly. It can be added to the current class, if that is the scope:
class A
def foo
def bar; p “BAR”; end
end
end
a = A.new
b = A.new
a.foo
b.bar # ==> “BAR”
On Mar 2, 2004, at 10:44 PM, Charles Comstock wrote:
Tim Bates wrote:
nobu.nokada@softhome.net wrote:
At Wed, 3 Mar 2004 15:44:46 +0900,
Charles Comstock wrote in [ruby-talk:94119]:Why is bar escaping the scope of foo? Is this a bug, or an
unintended feature?Probably quite intentional; I quite often use it for dynamic
(re)definition of methods and would be annoyed if it went away…I suggest if you need this behaviour, use a proc literal assigned to a
local variable, thus:def foo(x)
bar = proc do |n|
n + 1
end
bar.call(x) # or bar
endfoo(5) # → 6
bar(5) # → wtf? I don’t know what bar is.Tim.
Nah, I don’t really need it, I was just trying to scope out what the
language was capable of scoping wise. Out of curiosity, why don’t you
just use an eval to change function definitions? It would be much nicer
I think if it worked as another way to generate a closure, but bound in
the outer scope. But maybe I’m just not following what your using it for.
Charles Comstock
Joel VanderWerf wrote:
Method definitions are scoped the same way as @variables; the new
method is added to the current instance. It doesn’t matter if you do
it at the^^^^^^^^
Not exactly. It can be added to the current class, if that is the scope:
class A
def foo
def bar; p “BAR”; end
end
end
It’s still the current instance. The current instance here happens
to be a class.
Hal
Hal Fulton wrote:
Joel VanderWerf wrote:
Method definitions are scoped the same way as @variables; the new
method is added to the current instance. It doesn’t matter if you do
it at the^^^^^^^^
Not exactly. It can be added to the current class, if that is the scope:
class A
def foo
def bar; p “BAR”; end
end
endIt’s still the current instance. The current instance here happens
to be a class.
That use of “current instance” is confusing to me. Maybe “current
definition scope” would be better. Words are more confusing than code…
class A
def foo
p self
def bar; p “BAR”; end
end
end
a = A.new
a.foo # ==> #<A:0x401c6da4>
Inside #foo, self refers to the instance of A. Yet, as my previous
example showed, the method was added as an instance method of class A,
not as a method of object A or as a singleton method of the instance of A.
Charles Comstock wrote:
Out of curiosity, why don’t you just use an eval to change function
definitions?
I do. Watch:
def mk_func(:name)
eval <<-EOF
def #{name}(foo)
puts foo
end
EOF
end
Even when using eval, you’ve got to use a def keyword somewhere to
define a method. As far as I’m concerned, the example above should be
equivalent to
def mk_func2
def bar(foo)
puts foo
end
end
With the exception of course that the name of the function is not
dynamic, which is why we use eval in the first place. The point I’m
making, however, is that the scoping rules for the inner function in
both examples should be equivalent, and that without the scoping being
as it is I would be unable to dynamically define methods in this manner.
Tim.
–
Tim Bates
tim@bates.id.au
Joel VanderWerf wrote:
Hal Fulton wrote:
It’s still the current instance. The current instance here happens
to be a class.That use of “current instance” is confusing to me. Maybe “current
definition scope” would be better. Words are more confusing than code…
[snip]
I think I have misspoken. Let me examine this. Sorry…
Hal
Hi –
Charles Comstock wrote:
Out of curiosity, why don’t you just use an eval to change function
definitions?I do. Watch:
def mk_func(:name)
eval <<-EOF
def #{name}(foo)
puts foo
end
EOF
endEven when using eval, you’ve got to use a def keyword somewhere to
define a method.
You can use define_method, if you want to avoid both eval and def.
Also, this gives you some control over scope, because you can put the
new method in either the class of the object (so that other instances
will be able to call it) or in the object’s singleton class.
class A
def mk_func(n)
self.class.class_eval {
define_method(n, proc {|foo| puts foo })
}
end
end
(Yes, I know that class_eval is in the eval family But you can
avoid eval’ing strings this way.)
David