On Mon, Jun 12, 2006 at 07:19:10PM +0900, Daniel S. wrote:
} Gregory S. wrote:
} >Sure, I understand. And yes, that would fix it. Take a look at the
complete
} >solution I posted at
} >Ruby, iOS, and Other Development: Mixing in Class Methods
}
} Still think it’s rather complicated. Here’s what I’ve got so far,
using
} a slightly different approach than you:
}
} class Module
} def meta_module(&block)
} @meta_module ||= Module.new
} @meta_module.module_eval(&block)
} extend(@meta_module)
Why should the module extend the meta_module?
} end
}
} def included(mod)
} mod.extend(@meta_module ||= Module.new)
Again, if it’s a module why should it extend the meta_module?
} if mod.kind_of? Module
This definitely won’t work. You need to check for Class, not Module.
Check
it out:
% irb
irb(main):001:0> Object.kind_of? Module
=> true
} if mod.instance_variables.include? “@meta_module”
} other_meta_module = mod.instance_variable_get(:@meta_module)
} other_meta_module.send(:include, @meta_module)
Pretty much what I have.
} else
} mod.instance_variable_set(:@meta_module, @meta_module)
} end
} end
} end
} end
That last line is dangerous. Consider the following usage:
module M
meta_module {
def bar
“class method bar() was defined in M”
end
}
end
class Foo
include M
end
module N
include M
meta_module {
def bar
“pwn3d!”
end
}
end
puts Foo.bar
By setting the including module’s instance variable to be the same as
the
included module’s instance variable you allow the including module to
overwrite methods unexpectedly. That’s why I give the including module
its
own new module and have it include the included module’s module. It
preserves the inclusion semantics.
} There may still be flaws, but I don’t think it’s too bad. Notice the
use
} of meta_module' -- thought it was better than
class_methods’, though
} I’m not sure it’s perfect, either.
I don’t see anything particularly meta about it, but that may just be
me.
} Cheers,
} Daniel
–Greg