Why do inner methods count in outer scope?

  • Thread starter Charles Comstock
  • Start date
C

Charles Comstock

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
 
N

nobu.nokada

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.

# suspect this is still transient behavior and will be changed
# in the future, just my 2yen.
 
T

Tim Bates

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[x]
end

foo(5) # -> 6
bar(5) # -> wtf? I don't know what bar is.


Tim.
 
C

Charles Comstock

Tim said:
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[x]
end

foo(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
 
M

Mark Hubbart

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?

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
 
J

Joel VanderWerf

Mark said:
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"
 
H

Hal Fulton

Joel said:
^^^^^^^^

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
 
J

Joel VanderWerf

Hal said:
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...

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.
 
H

Hal Fulton

Joel said:
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
 
T

Tim Bates

Charles said:
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.
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top