It seems difficult to invoke… I tried this…
but somehow a symbol is expected ?
ruby a.rb
“foo”
a.rb:4:in `public’: nil is not a symbol (TypeError)
from a.rb:4
expand -t2 a.rb
def m
p “foo”
end
public m
class C
def m(scope)
eval(“m”, scope)
end
end
C.m(binding)
···
On Fri, 19 Mar 2004 08:25:45 +0900, Bill Kelly wrote:
It seems difficult to invoke… I tried this…
but somehow a symbol is expected ?
[snip weird problem]
Ok… now it works
ruby a.rb
“foo”
“foo2”
expand -t2 a.rb
def m(args)
p args
end
class C
def self.m
eval(‘m(“foo”)’, TOPLEVEL_BINDING)
end
def m
eval(‘m(“foo2”)’, TOPLEVEL_BINDING)
end
end
C.m
C.new.m
···
On Fri, 19 Mar 2004 00:31:46 +0100, Simon Strandgaard wrote:
On Fri, 19 Mar 2004 08:25:45 +0900, Bill Kelly wrote:
It seems difficult to invoke… I tried this…
but somehow a symbol is expected ?
Yup:
public :m
Here’s some samples:
def foo
puts "outer"
end
class Bar
def foo
"inner"
end
end
Bar.new.foo # => "inner"
foo # => "outer"
class Bar
def foo
super
end
end
Bar.new.foo # => "inner"
Notice that Bar -inherits- foo. When you make an “outer” method, you’re
actually adding it as a private that’s part of Object. That’s why
public :foo
at the top level works the way it does.
···
On Fri, Mar 19, 2004 at 08:39:31AM +0900, Simon Strandgaard wrote:
On Fri, 19 Mar 2004 08:25:45 +0900, Bill Kelly wrote:
ruby a.rb
“foo”
a.rb:4:in `public’: nil is not a symbol (TypeError)
from a.rb:4
expand -t2 a.rb
def m
p “foo”
end
public m
class C
def m(scope)
eval(“m”, scope)
end
end
C.m(binding)
ruby a.rb
“foo”
“foo2”
expand -t2 a.rb
def m(args)
p args
end
class C
def self.m
eval(‘m(“foo”)’, TOPLEVEL_BINDING)
end
def m
eval(‘m(“foo2”)’, TOPLEVEL_BINDING)
end
end
C.m
C.new.m
My only problem with the ‘super’ approach is that it doesn’t really
execute the top-level version of the method; it executes the next
version up in the method search path, which may or may not be the
top-level version.
def x
puts “Top level”
end
class A
def x
puts “A#x”
end
end
class B < A
def x
super
end
end
B.new.x # => A#x
So it’s not a reliable way of reaching back to the top level.
My only problem with the ‘super’ approach is that it doesn’t really
execute the top-level version of the method; it executes the next
version up in the method search path, which may or may not be the
top-level version.
So it’s not a reliable way of reaching back to the top level.
This works:
def quux(n)
“q#{“u”*n}x”
end
class Foo
def quux(n)
“foo’s q#{“u”*n}x”
end
end
class Bar < Foo
def quux(n)
Object.new.quux(n)
end
end
It’s still better than Kernel.x in the sense that ‘self’ is the right one and
it will work with private instance methods.
The following solves the problem completely IMHO
class Object
def my_call(klass, method, *args, &block)
klass.instance_method(method).bind(self).call(*args, &block)
end
end
def spleen
puts “Object#spleen”
end
class A
def spleen
puts “A#spleen”
end
end
class Blah < A
def spleen
super # uses A’s
puts “now Object’s”
my_call(Object, :spleen) # uses Object’s
end
end
Blah.new.spleen
batsman@tux-chan:/tmp$ ruby dispatch.rb
A#spleen
now Object’s
Object#spleen
One could try to find a better syntax for that, maybe
:Object.call.spleen
or
:Object[:spleen].call
but I’m not so fond of them (implementing this sort of things is fun though :).
···
On Fri, Mar 19, 2004 at 11:27:26AM +0900, David A. Black wrote:
My only problem with the ‘super’ approach is that it doesn’t really
execute the top-level version of the method; it executes the next
version up in the method search path, which may or may not be the
top-level version.
def x
puts “Top level”
end
class A
def x
puts “A#x”
end
end
class B < A
def x
super
end
end
B.new.x # => A#x
So it’s not a reliable way of reaching back to the top level.
–
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com