Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > local_method_missing possible

Reply
Thread Tools

local_method_missing possible

 
 
trans. (T. Onoma)
Guest
Posts: n/a
 
      09-26-2004

I'm wondering how feasible it might be to implement a local_method_missing
hook in core Ruby? What I mean by that is a hook like method_missing, but one
that only is concerned with the methods defined in the current class context.

E.g.

class A
def a; end
end
class B < A
def local_method_missing(sym, *args)
puts "Can't find #{sym}."
end
end

B.new.a
#=> Can't find a.

Thanks,
T.



 
Reply With Quote
 
 
 
 
Markus
Guest
Posts: n/a
 
      09-26-2004

I'm not sure I understand what you're getting at. Why would you
subclass A if you didn't want to inherit any of the methods from A?

-- Markus

On Sat, 2004-09-25 at 18:57, trans. (T. Onoma) wrote:
> I'm wondering how feasible it might be to implement a local_method_missing
> hook in core Ruby? What I mean by that is a hook like method_missing, but one
> that only is concerned with the methods defined in the current class context.
>
> E.g.
>
> class A
> def a; end
> end
> class B < A
> def local_method_missing(sym, *args)
> puts "Can't find #{sym}."
> end
> end
>
> B.new.a
> #=> Can't find a.
>
> Thanks,
> T.
>




 
Reply With Quote
 
 
 
 
trans. (T. Onoma)
Guest
Posts: n/a
 
      09-26-2004
On Saturday 25 September 2004 10:42 pm, Markus wrote:
> I'm not sure I understand what you're getting at. Why would you
> subclass A if you didn't want to inherit any of the methods from A?


Hi.

It's related to AOP. The basic idea is to be able to reroute method
invocations.

class A
def a; puts "here"; end
end
class B < A
def b(meth)
puts "before"
send(meth)
puts "after"
end
def local_method_missing(sym, *args)
if /^a/ =~ meth.to_s
b(meth)
end
end
end

T.

--
( o _ カラチ
// trans.
/ \ http://www.velocityreviews.com/forums/(E-Mail Removed)

I don't give a damn for a man that can only spell a word one way.
-Mark Twain



 
Reply With Quote
 
Markus
Guest
Posts: n/a
 
      09-26-2004
1) Wouldn't that cause infinite recursion if you called B.new.a?
2) Is this something like CLOS (common lisp object system) around
methods? (See http://www.aiai.ed.ac.uk/~jeff/clos-guide.html). If so,
I have an partial implementation that works in 1.8.0 (and I hope will
work in 1.8.2 final)

-- Markus



On Sat, 2004-09-25 at 20:10, trans. (T. Onoma) wrote:
> On Saturday 25 September 2004 10:42 pm, Markus wrote:
> > I'm not sure I understand what you're getting at. Why would you
> > subclass A if you didn't want to inherit any of the methods from A?

>
> Hi.
>
> It's related to AOP. The basic idea is to be able to reroute method
> invocations.
>
> class A
> def a; puts "here"; end
> end
> class B < A
> def b(meth)
> puts "before"
> send(meth)
> puts "after"
> end
> def local_method_missing(sym, *args)
> if /^a/ =~ meth.to_s
> b(meth)
> end
> end
> end
>
> T.




 
Reply With Quote
 
jim@freeze.org
Guest
Posts: n/a
 
      09-27-2004
* trans. (T. Onoma) <(E-Mail Removed)> [2004-09-26 12:10:59 +0900]:

> It's related to AOP. The basic idea is to be able to reroute method
> invocations.
>
> class A
> def a; puts "here"; end
> end
> class B < A
> def b(meth)
> puts "before"
> send(meth)
> puts "after"
> end
> def local_method_missing(sym, *args)
> if /^a/ =~ meth.to_s
> b(meth)
> end
> end
> end


Could you just use super?

class A
def a; puts "in a"; end
end
class B < A
def a
puts "before"
super
puts "after"
end
end

B.new.a

--
Jim Freeze


 
Reply With Quote
 
trans. (T. Onoma)
Guest
Posts: n/a
 
      09-27-2004
On Sunday 26 September 2004 02:01 am, Markus wrote:
> 1) Wouldn't that cause infinite recursion if you called B.new.a?
> 2) Is this something like CLOS (common lisp object system) around
> methods? (See http://www.aiai.ed.ac.uk/~jeff/clos-guide.html). If so,
> I have an partial implementation that works in 1.8.0 (and I hope will
> work in 1.8.2 final)


1) Good point.

Actually, what is really needed, to make this work well, is a way to send the
method on, up to the next level of the class/module hierarchy, without
rerouting back to the bottom.

2) Thanks. I actually have many implementations of wraps already -- I take it
you are using alias?

Obviously local_method_missing is just a proto-idea, but what it intendeds to
solve is related to dynamically creating wraps that apply to collections of
methods, not just a single method. Also, it is for use in a specific context,
namely a subclass.

So the question is this: Given a class and a predefined 'wrapping' method, how
do I create a subclass and a submethod to effect multiple methods in the
class. Obviously I could just create a submethod for each class method, but
that seems rather bulky.

Hope that makes enough sense,
T.


 
Reply With Quote
 
trans. (T. Onoma)
Guest
Posts: n/a
 
      09-27-2004
On Sunday 26 September 2004 10:33 pm, (E-Mail Removed) wrote:
> > class A
> > def a; puts "here"; end
> > end
> > class B < A
> > def b(meth)
> > puts "before"
> > send(meth)
> > puts "after"
> > end
> > def local_method_missing(sym, *args)
> > if /^a/ =~ meth.to_s
> > b(meth)
> > end
> > end
> > end

>
> Could you just use super?
>
> class A
> def a; puts "in a"; end
> end
> class B < A
> def a
> puts "before"
> super
> puts "after"
> end
> end


The idea is to submethod multiple methods in one fell-swoop. Hence:

if /^a/ =~ meth.to_s

If you have any ideas on other ways to do this, I would love to hear them.

Thanks,
T.


 
Reply With Quote
 
Jamis Buck
Guest
Posts: n/a
 
      09-27-2004
trans. (T. Onoma) wrote:
> On Sunday 26 September 2004 10:33 pm, (E-Mail Removed) wrote:
>
>>> class A
>>> def a; puts "here"; end
>>> end
>>> class B < A
>>> def b(meth)
>>> puts "before"
>>> send(meth)
>>> puts "after"
>>> end
>>> def local_method_missing(sym, *args)
>>> if /^a/ =~ meth.to_s
>>> b(meth)
>>> end
>>> end
>>> end

>>
>>Could you just use super?
>>
>> class A
>> def a; puts "in a"; end
>> end
>> class B < A
>> def a
>> puts "before"
>> super
>> puts "after"
>> end
>> end

>
>
> The idea is to submethod multiple methods in one fell-swoop. Hence:
>
> if /^a/ =~ meth.to_s
>
> If you have any ideas on other ways to do this, I would love to hear them.


Well, it's not very pretty, but what about:

1) aliasing all methods of the subclass to something else (mangling
them, basically),

2) Using "method_missing" to intercept and redirect calls to those methods,

3) and using "self.class.instance_methods(false).include?(. ..)" to
determine whether the method was defined in the subclass or a superclass...

If this isn't clear enough (and it may very well not be!) I could try
posting some pseudo-code...

- Jamis

--
Jamis Buck
(E-Mail Removed)
http://www.jamisbuck.org/jamis


 
Reply With Quote
 
Mauricio Fernndez
Guest
Posts: n/a
 
      09-27-2004
On Tue, Sep 28, 2004 at 01:28:47AM +0900, trans. (T. Onoma) wrote:
> > Could you just use super?
> >
> > class A
> > def a; puts "in a"; end
> > end
> > class B < A
> > def a
> > puts "before"
> > super
> > puts "after"
> > end
> > end

>
> The idea is to submethod multiple methods in one fell-swoop. Hence:
>
> if /^a/ =~ meth.to_s
>
> If you have any ideas on other ways to do this, I would love to hear them.


batsman@tux-chan:/tmp$ cat gdfgrre.rb

module Magic
def wrap_method(*names, &block)
names.each do |name|
old = instance_method(name)
define_method(name) do |*a| # |*a, &b| on 1.9
block.call(name, old.bind(self), *a) # &b on 1.9
end
end
end
end

class A
def foo; puts "A#foo" end
def bar; puts "A#bar" end
end

class B < A
extend Magic

wrap_method(:foo, :bar) do |meth, old|
puts "pre"
puts "About to call #{meth}"
if meth.to_s == "foo"
puts "special action for foo!"
end
old.call
puts "post"
end
end

b = B.new
b.foo
b.bar
batsman@tux-chan:/tmp$ ruby gdfgrre.rb
pre
About to call foo
special action for foo!
A#foo
post
pre
About to call bar
A#bar
post

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com



 
Reply With Quote
 
Markus
Guest
Posts: n/a
 
      09-27-2004
On Mon, 2004-09-27 at 09:53, Mauricio Fernández wrote:
> module Magic
> def wrap_method(*names, &block)
> names.each do |name|
> old = instance_method(name)
> define_method(name) do |*a| # |*a, &b| on 1.9
> block.call(name, old.bind(self), *a) # &b on 1.9
> end
> end
> end
> end


Note, though, that this will fail under 1.8.1 & 1.8.2Pre (but not, I
hope, under later versions) because of the change in block/proc
semantics. See:

http://blade.nagaokaut.ac.jp/cgi-bin...by-talk/113629

http://blade.nagaokaut.ac.jp/cgi-bin...by-talk/113697

(and of course the follow-ons), if you haven't been following that
thread already.

-- Markus



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
efficient data loading with Python, is that possible possible? igor.tatarinov@gmail.com Python 10 12-14-2007 04:44 PM
is it possible to possible to create an iterator from a callback interace? aninnymouse@gmail.com C Programming 4 02-21-2006 02:10 PM
XML + XSD: Is it possible to get all possible Values for an Element? Markus Java 1 11-22-2005 02:51 PM
Possible to connect 2 computers via USB? Michael Giroux Wireless Networking 2 09-02-2004 03:27 AM
Possible domain related wireless problem =?Utf-8?B?QWxpIEQ=?= Wireless Networking 0 08-10-2004 01:59 AM



Advertisments