Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > special super call for module class-level inclusion

Reply
Thread Tools

special super call for module class-level inclusion

 
 
Trans
Guest
Posts: n/a
 
      08-28-2007
Since I've come upon the issue again, I reckon, it's as good time as
any to put this in the air.

The issue, again, is that module class methods are not
"inherited" (for lack of a better word). In the past I've argued for
this, but it has been consistently argued down due to the extraneous
methods it would add to classes. However, it occurs to me that the
core problem that I continually face for the lack of this, it simply
that I can't call super in a class level method and expect it to move
through included module methods. The reason this is such a problem, it
that it makes it very difficult to create an "inheriting variable".
This is the reason Facets contains inheritor.rb, but even that is
limited to only simple cases.

To make this clear, here is a simple example of the idea:

class X
include M
def self.foo
[ 'Xfoo' ]
end
end

module M
def self.foo
[ 'Mfoo' ] + super
end
end

class Y < X
include M
def self.foo
[ 'Yfoo' ] + super
end
end

Y.foo #=> [ 'Yfoo', 'Xfoo' ]

As you can see there is no 'Mfoo' in the list.

If your're wondering how this is useful, consider any use-case where
meta-information needs to associated to a method. Just as methods are
inherited so too their meta-information. Possible uses are annotations
and pre, post, around wraps.

So the thought I had today is that rather then full inclusion at the
class-level, that we might simply have an alternate #super call that
would traverse the include modules class methods as well as classes. I
realize that might be tricky to implement, but it would satisfy the
need without all the unwanted baggage.

T.


 
Reply With Quote
 
 
 
 
Daniel DeLorme
Guest
Posts: n/a
 
      08-29-2007
Trans wrote:
> The issue, again, is that module class methods are not
> "inherited" (for lack of a better word). In the past I've argued for
> this, but it has been consistently argued down due to the extraneous
> methods it would add to classes. However, it occurs to me that the


IMHO the reason for this problem is that modules serve double duty as
both mixins (instance methods) and namespaces (class methods).

> core problem that I continually face for the lack of this, it simply
> that I can't call super in a class level method and expect it to move
> through included module methods. The reason this is such a problem, it
> that it makes it very difficult to create an "inheriting variable".
> This is the reason Facets contains inheritor.rb, but even that is
> limited to only simple cases.


The problem piqued my interest so despite my best attempts at
self-control I wound up writing code for it :-/

class Module
attr_accessor :class_methods_module
def class_methods(&block)
self.class_methods_module ||= begin
mod = Module.new
core = (class << self; self; end)
prev = core.method(:included)
core.send(:define_method, :included) do |into_class|
prev.call(into_class)
into_class.extend(mod)
end
mod
end
class_methods_module.class_eval(&block)
end
end

class Class
def class_methods(&block)
instance_eval(&block)
end
end

module M
def a;"Ma";end
class_methods do
def b;"Mb";end
end
end

class C
include M
def a;"Ca"+super;end
class_methods do
def b;"Cb"+super;end
end
end

puts C.new.a #=> CaMa
puts C.b #=> CbMb

 
Reply With Quote
 
 
 
 
Trans
Guest
Posts: n/a
 
      08-31-2007


On Aug 29, 4:58 pm, Daniel DeLorme <(E-Mail Removed)> wrote:

> The problem piqued my interest so despite my best attempts at
> self-control I wound up writing code for it :-/
>
> class Module
> attr_accessor :class_methods_module
> def class_methods(&block)
> self.class_methods_module ||= begin
> mod = Module.new
> core = (class << self; self; end)
> prev = core.method(:included)
> core.send(:define_method, :included) do |into_class|
> prev.call(into_class)
> into_class.extend(mod)
> end
> mod
> end
> class_methods_module.class_eval(&block)
> end
> end
>
> class Class
> def class_methods(&block)
> instance_eval(&block)
> end
> end


Nice work! That's not the easiest piece of meta-code to write. But has
been touched on before. Facets has had a version of this for a while
now, used extensively by Nitro/Og, written primarily by Daniel
Schierbeck. It looks like this:

class Module


alias_method :append_features_without_class_extension, :append_features

def class_extension(&block)
@class_extension ||= Module.new do
def self.append_features(mod)
append_features_without_class_extension(mod)
end
end
@class_extension.module_eval(&block) if block_given?
@class_extension
end

private :class_extension

def append_features(mod)
append_features_without_class_extension(mod)
mod.extend(class_extension)
if mod.instance_of? Module
mod.__send__(:class_extension).__send__(:include,
class_extension)
end
end

end

class Class
undef_method :class_extension
end

Your definition of Class's method is an interesting idea and may make
a good adjustment Facets' undef_method.

On the downside, this approach doesn't RDoc well --actually it doesn't
RDOc at all. Also, many people seem put off by the general aesthetic
of it too.

As of late I've been leaning toward the idea of the old ClassMethods
module solution, but modifying #include (or a similar new method) to
handle the extension rather than using the included callback.
(Personally, I'd also prefer a better name than ClassMethods, but
that's of minor consequence).

T.


 
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
Ncurses module inclusion question Jos Backus Ruby 1 08-29-2008 07:14 PM
inclusion of module: differences Leon Bogaert Ruby 2 05-29-2008 07:58 PM
elementtree and inclusion of special characters =?iso-8859-1?B?QW5kcuk=?= Python 1 06-03-2006 05:29 PM
super.super.super how? Java 24 02-24-2005 10:51 PM
mod_ruby+eruby module inclusion confusion Mark J. Reed Ruby 0 02-18-2005 07:40 PM



Advertisments