Exercise in Frustration

T

Trans

I would like to see someone else do this. I've simplified the issue to
a small exercise. Given:

module MyEnhancement

def attr_accessor(*a)
put "doing something special with #{a.join(' ')}"
super(*a)
end

end

This module can be used in any class or module simply by using
#extend.

class SomeClass
extend MyEnhancement
end

Great. However, I also want the end-user of this library to be able
effect all classes and modules with a single extend (or include) as
well, if they so choose. Eg.

class Module
include MyEnhancement
end

It would also be nice if the module's methods can be made to work from
the toplevel (main):

extend MyEnhancement

Of course, these last two pieces of code do not work.

In attempting to implement this, I have found myself resorting to
unDRY, ugly, hacky code, that always seems to have a bug in it
somewhere. It's infuriating. This is not how programming Ruby is
supposed to be!
 
P

Pit Capitain

2009/2/15 Trans said:
Great. However, I also want the end-user of this library to be able
effect all classes and modules with a single extend (or include) as
well, if they so choose. Eg.

class Module
include MyEnhancement
end

Is the problem here that Module defines its own #attr_accessor
shadowing the new one?
It would also be nice if the module's methods can be made to work from
the toplevel (main):

extend MyEnhancement

What should #attr_accessor do in the context of the toplevel object?
Maybe you can show us another example?
In attempting to implement this, I have found myself resorting to
unDRY, ugly, hacky code, that always seems to have a bug in it
somewhere. It's infuriating. This is not how programming Ruby is
supposed to be!

Hmm, I think this will be hacky indeed.

Regards,
Pit
 
R

Robert Dober

This is pretty much the simplest I could come up with

http://pastie.org/389760

an interesting pattern indeed.

HTH
Robert

--
There are some people who begin the Zoo at the beginning, called
WAYIN, and walk as quickly as they can past every cage until they get
to the one called WAYOUT, but the nicest people go straight to the
animal they love the most, and stay there. ~ A.A. Milne (from
Winnie-the-Pooh)
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]
Great. However, I also want the end-user of this library to be able
effect all classes and modules with a single extend (or include) as
well, if they so choose. Eg.

class Module
include MyEnhancement
end



I came up with this a while ago: http://gist.github.com/25104. It's a pretty
big hack but lets you write modules that override the behaviour of classes
they're mixed into.
 
T

Trans

Is the problem here that Module defines its own #attr_accessor
shadowing the new one?

Yes, that's part of the issue here. In the case where one extends a
class, #super works, in the case of including it into Module, one had
to do the whole alias chaining thing.

As I worked on this it made me think that it would be nice if their
were a MetaKernel for the Module's methods, just as there is a Kernel
for Object's methods. That would at least DRY this part up.
What should #attr_accessor do in the context of the toplevel object?
Maybe you can show us another example?

What it normally does, define a method wrapping an instance variable.
Having it at toplevel isn't that important in this case. But I have a
similar case for an original method (#annotator) where it is.

If the toplevel object were a self extended module, this would not be
an issue either. I know I've brought this up more than a few times,
but I don't recall Matz ever addressing it, and saying why it's not a
good idea. Sure wish I knew, with all the meta-coding I've done this
is one of the few issues I keep bumping my head against.
Hmm, I think this will be hacky indeed.

Unfortunately, what I've managed to get to work very much is. You can
see my hacks for the real deal here:

http://anise.rubyforge.org/git?p=3Danise.git;a=3Dtree;f=3Dlib/anise;h=3Dd64=
d5a9ecef1c1b8e1c76a7d84c8462f3aad7ee6;hb=3DHEAD

Thanks,
T.
 
T

Trans

This is pretty much the simplest I could come up with

http://pastie.org/389760

an interesting pattern indeed.

That was fast :)

I ended up doing something similar to this. Though I wanted to use
#super were I could so I created two versions of the attr_ overrides,
one with #super and one using #alias_method. I also overrode
#append_features instead of using #included. You can see it here:

http://anise.rubyforge.org/git?p=3Danise.git;a=3Dblob;f=3Dlib/anise/attri=
bute.rb;h=3Dde5f6e05b0a444ee9de3f4130f6f5573a5f38299;hb=3DHEAD

Thanks Robert,
T.
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

2009/2/16 Trans said:
Sort of like a traits system?



I'm afraid I don't know enough about traits and how they differ from mixins
to be able to answer that. In fact, if you know of any good reference
material on traits I'd quite like to give it a read.
 
R

Robert Dober

R

Robert Dober

I ended up doing something similar to this. Though I wanted to use
#super were I could so I created two versions of the attr_ overrides,
one with #super and one using #alias_method. I also overrode
#append_features instead of using #included. You can see it here:
Ah interesting, that would cover extend too, right?
Interesting stuff.
R
--
There are some people who begin the Zoo at the beginning, called
WAYIN, and walk as quickly as they can past every cage until they get
to the one called WAYOUT, but the nicest people go straight to the
animal they love the most, and stay there. ~ A.A. Milne (from
Winnie-the-Pooh)
 

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
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top