[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

redefining methods

ara.t.howard

7/31/2007 2:48:00 PM


i was playing with this last night, thought some here might be
interested:

http://drawohara.tumblr.com/po...

cheers.

a @ http://draw...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




11 Answers

dohzya

7/31/2007 5:27:00 PM

0

Le mardi 31 juillet 2007 à 23:48 +0900, ara.t.howard a écrit :
> i was playing with this last night, thought some here might be
> interested:
>
> http://drawohara.tumblr.com/po...
>
> cheers.
>
> a @ http://draw...
> --
> we can deny everything, except that we have the possibility of being
> better. simply reflect on that.
> h.h. the 14th dalai lama

Just for the syntax, I don't like :
---
redefining :foo do
def foo(*a, &b) super.reverse end
end
---
I prefer :
---
redefining :foo do |*a, &b|
super.reverse
end
---
Greater, it isn't ?
---

However, there is an other way :
---
redefining :foo do |&old| # &old or old, see after
def foo(*a, &b) old.call.reverse end
end
---
and maybe...
---
redefining :foo do |*olds| # list, ordered (asc or desc ?)
def foo(*a, &b) (olds.shift.call + olds.shift.call).reverse end
# maybe add a shortcut for shift.call...
end
---

Regards

--
Etienne Vallette d'Osia


ara.t.howard

7/31/2007 5:49:00 PM

0


On Jul 31, 2007, at 11:27 AM, dohzya wrote:

> Le mardi 31 juillet 2007 à 23:48 +0900, ara.t.howard a écrit :
>> i was playing with this last night, thought some here might be
>> interested:
>>
>> http://drawohara.tumblr.com/po...
>>
>> cheers.
>>
>> a @ http://draw...
>> --
>> we can deny everything, except that we have the possibility of being
>> better. simply reflect on that.
>> h.h. the 14th dalai lama
>
> Just for the syntax, I don't like :
> ---
> redefining :foo do
> def foo(*a, &b) super.reverse end
> end
> ---
> I prefer :
> ---
> redefining :foo do |*a, &b|
> super.reverse
> end
> ---
> Greater, it isn't ?

absolutely. and when define_method takes a block that would indeed
by the way to do it.

> ---
>
> However, there is an other way :
> ---
> redefining :foo do |&old| # &old or old, see after
> def foo(*a, &b) old.call.reverse end
> end
> ---

this can't work though - old is not in scope inside foo - only with
define_method would that be possible, but there you lose the ability
to define methods which themselves take blocks...

> and maybe...
> ---
> redefining :foo do |*olds| # list, ordered (asc or desc ?)
> def foo(*a, &b) (olds.shift.call + olds.shift.call).reverse end
> # maybe add a shortcut for shift.call...
> end
> ---

again - same issue with scoping. although i agree and more closure
based solution would be nice. for now though - i don't think it's
possible. i'd be very happy to be proven wrong though! ;-)

kind regards.

a @ http://draw...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Pit Capitain

7/31/2007 6:10:00 PM

0

2007/7/31, ara.t.howard <ara.t.howard@gmail.com>:
> i was playing with this last night, thought some here might be
> interested:
>
> http://drawohara.tumblr.com/po...

Hi Ara, since I don't know the implementation of Rails'
alias_method_chain, I can't comment on which is better, so just a few
remarks concerning your code:

* Syntax: like Étienne, I, too, don't like that it is necessary to
repeat the method name in both the #redefining call and the method
definition. Couldn't you just call #redefining without an argument and
look in the new module which methods have been defined there?

* Implementation: I haven't checked in detail, but I think you could
get problems with the class variable when there's a class hierarchy.

* Implementation: currently, the method chains are only used as a flag
whether to create the "initial" module or not. Do you plan to use it
for other things? Otherwise you don't need an array with all the
intermediate modules.

Btw. nice use of the BEGIN block!

Regards,
Pit

Bil Kleb

7/31/2007 7:08:00 PM

0

Pit Capitain wrote:
>
> Btw. nice use of the BEGIN block!

Yes.

That was a question that came up at the Advanced Ruby Studio
in Reston a couple weeks ago: of what practical use are those
BEGIN/END things anyway? ;)

Regards,
--
Bil Kleb
http://nasarb.rub...

ara.t.howard

7/31/2007 7:22:00 PM

0


On Jul 31, 2007, at 12:09 PM, Pit Capitain wrote:

> * Syntax: like Étienne, I, too, don't like that it is necessary to
> repeat the method name in both the #redefining call and the method
> definition. Couldn't you just call #redefining without an argument and
> look in the new module which methods have been defined there?

indeed you could/would. just playing now. patches welcome! ;-)

>
> * Implementation: I haven't checked in detail, but I think you could
> get problems with the class variable when there's a class hierarchy.

yeah - a class instance var would be the way to go - i was just
saving on typing for demo..

>
> * Implementation: currently, the method chains are only used as a flag
> whether to create the "initial" module or not. Do you plan to use it
> for other things? Otherwise you don't need an array with all the
> intermediate modules.
>

hmmm - you mean use only the two: the initial and subsequent? i
think that would work... i was indeed thinking of being able to call
a 'specific super' though...

> Btw. nice use of the BEGIN block!

i like the idiom, but the error reporting and require semantics stink
- it's nice for examples though ;-)

cheers.

a @ http://draw...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




ara.t.howard

7/31/2007 8:33:00 PM

0


On Jul 31, 2007, at 12:09 PM, Pit Capitain wrote:

> 2007/7/31, ara.t.howard <ara.t.howard@gmail.com>:
>> i was playing with this last night, thought some here might be
>> interested:
>>
>> http://drawohara.tumblr.com/po...
>
> Hi Ara, since I don't know the implementation of Rails'
> alias_method_chain, I can't comment on which is better, so just a few
> remarks concerning your code:
>
> * Syntax: like Étienne, I, too, don't like that it is necessary to
> repeat the method name in both the #redefining call and the method
> definition. Couldn't you just call #redefining without an argument and
> look in the new module which methods have been defined there?
>
> * Implementation: I haven't checked in detail, but I think you could
> get problems with the class variable when there's a class hierarchy.
>
> * Implementation: currently, the method chains are only used as a flag
> whether to create the "initial" module or not. Do you plan to use it
> for other things? Otherwise you don't need an array with all the
> intermediate modules.
>
> Btw. nice use of the BEGIN block!
>
> Regards,
> Pit
>


updated:

http://drawohara.tumblr.com/po...

i played some cannot seem to come up with a way to avoid having the
stack of modules and also maintain super semantics across multiple
invocations - anyone else have a go?


a @ http://draw...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Robert Dober

7/31/2007 8:38:00 PM

0

On 7/31/07, ara.t.howard <ara.t.howard@gmail.com> wrote:
>
> i was playing with this last night, thought some here might be
> interested:
>
> http://drawohara.tumblr.com/po...
>
> cheers.
>
> a @ http://draw...
As Etienne and Pit pointed it out (guys are you using 1.9 and pointing
fingers at us ;)?) the &blk sntax in block is really missing.
This is a big issue here

if method_chain.empty?
m = Module.new do
class_variable_set "@@#{ method }", this.module_eval{
instance_method method }
module_eval "def #{ method }(*a, &b) @@#{ method
}.bind(self).call(*a, &b) end"
end
remove_method method
include m
end
As it is soo easy to have a class with @@#{method} in your class :(
I do not see any solution, if only we could use closures with a
define_method m do |*args,&blk|

I know I am not DROP here :(

BTW
I would write

def method_chains
@method_chains ||= Hash.new
end

Cheers
Robert

P.S.
Nice work :)
--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein

Robert Dober

7/31/2007 8:42:00 PM

0

On 7/31/07, ara.t.howard <ara.t.howard@gmail.com> wrote:
>
> On Jul 31, 2007, at 12:09 PM, Pit Capitain wrote:
>
> > 2007/7/31, ara.t.howard <ara.t.howard@gmail.com>:
> >> i was playing with this last night, thought some here might be
> >> interested:
> >>
> >> http://drawohara.tumblr.com/po...
> >
> > Hi Ara, since I don't know the implementation of Rails'
> > alias_method_chain, I can't comment on which is better, so just a few
> > remarks concerning your code:
> >
> > * Syntax: like Étienne, I, too, don't like that it is necessary to
> > repeat the method name in both the #redefining call and the method
> > definition. Couldn't you just call #redefining without an argument and
> > look in the new module which methods have been defined there?
> >
> > * Implementation: I haven't checked in detail, but I think you could
> > get problems with the class variable when there's a class hierarchy.
> >
> > * Implementation: currently, the method chains are only used as a flag
> > whether to create the "initial" module or not. Do you plan to use it
> > for other things? Otherwise you don't need an array with all the
> > intermediate modules.
> >
> > Btw. nice use of the BEGIN block!
> >
> > Regards,
> > Pit
> >
>
>
> updated:
>
> http://drawohara.tumblr.com/po...
>
> i played some cannot seem to come up with a way to avoid having the
> stack of modules and also maintain super semantics across multiple
> invocations - anyone else have a go?
>
>
> a @ http://draw...
> --
> we can deny everything, except that we have the possibility of being
> better. simply reflect on that.
> h.h. the 14th dalai lama
>
>
>
>
>
Wow can you read my mind :), you fixed it already!! Very impressive
technique, but what a pain...

Robert

--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein

Pit Capitain

7/31/2007 9:51:00 PM

0

2007/7/31, ara.t.howard <ara.t.howard@gmail.com>:
> i played some cannot seem to come up with a way to avoid having the
> stack of modules and also maintain super semantics across multiple
> invocations - anyone else have a go?

Ara, I didn't mean you don't need a stack of modules, but you don't
need to store the modules in an array (yet).

> just playing now. patches welcome! ;-)

Not a patch, but a slightly different implementation based on your idea:

class C
def foo() 'f' end
def bar() 'b' end
def foobar() foo + bar end
end
c = C.new
p c.foobar # => "fb"

class C
redefining do
def foo() super + 'oo' end
end
end
p c.foobar # => "foob"

class C
redefining do
def bar() super + 'ar' end
end
end
p c.foobar # => "foobar"

class C
redefining do
def foo() super.reverse end
def bar() super.reverse end
end
end
p c.foobar # => "oofrab"


### the implementation

BEGIN {
class Class
def redefining &block
unless defined? @_org
org_mod = Module.new
@_org = { :mod => org_mod }
include org_mod
end

m = Module.new(&block)

(m.instance_methods(false) & instance_methods(false)).each do |method|
@_org[method] = instance_method method
@_org[:mod].module_eval <<-EOC
def #{method}(*a, &b)
org = self.class.instance_variable_get("@_org")
org["#{method}"].bind(self).call(*a, &b)
end
EOC
remove_method method
end

include m
end
end
}

I used the old way of getting at the original method (storing it
somewhere), because I'm not sure whether the garbage collector could
remove it if you only remember it's object_id.

Regards,
Pit

ara.t.howard

8/1/2007 9:41:00 PM

0


On Jul 31, 2007, at 3:51 PM, Pit Capitain wrote:

> 2007/7/31, ara.t.howard <ara.t.howard@gmail.com>:
>> i played some cannot seem to come up with a way to avoid having the
>> stack of modules and also maintain super semantics across multiple
>> invocations - anyone else have a go?
>
> Ara, I didn't mean you don't need a stack of modules, but you don't
> need to store the modules in an array (yet).
>
>> just playing now. patches welcome! ;-)
>
> Not a patch, but a slightly different implementation based on your
> idea:
>
> class C

<snip>

>
> I used the old way of getting at the original method (storing it
> somewhere), because I'm not sure whether the garbage collector could
> remove it if you only remember it's object_id.
>
> Regards,
> Pit
>

updated (and new commenting finally ;-) )

http://drawohara.tumblr.com/po...

nice work pit!

a @ http://draw...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama