K
Kirk Haines
So, on #ruby-lang an hour ago, Daniel Berger asked for ideas to make some
non-working code of his work. He's trying to come up with a way to
selectively mixin methods from a module into a class.
After some tinkering, I came up with this working, but ugly and definitely
improveable code to do it:
class Module
def use(mod, *methods)
c = Class.new
# Make a singleton that mixes everything in, so that we can cherrypick.
eval("class << c; include #{mod}; end")
methods.each do |m|
# There has to be a more elegant way to do this.
m_sym = m.to_sym
mc_sym = m.to_s.upcase.to_sym
um = c.method(m_sym)
self.const_set(mc_sym,um)
self.class_eval("def #{m.to_s}; #{mc_sym.to_s}.call; end")
end
end
end
module Foo
def a; 'abc'; end
def z; 'xyz'; end
end
class Bing
use(Foo, :a, 'z')
end
x = Bing.new
p x.a
p x.z
There has to be a more elegant way to do this. What is it?
Kirk Haines
non-working code of his work. He's trying to come up with a way to
selectively mixin methods from a module into a class.
After some tinkering, I came up with this working, but ugly and definitely
improveable code to do it:
class Module
def use(mod, *methods)
c = Class.new
# Make a singleton that mixes everything in, so that we can cherrypick.
eval("class << c; include #{mod}; end")
methods.each do |m|
# There has to be a more elegant way to do this.
m_sym = m.to_sym
mc_sym = m.to_s.upcase.to_sym
um = c.method(m_sym)
self.const_set(mc_sym,um)
self.class_eval("def #{m.to_s}; #{mc_sym.to_s}.call; end")
end
end
end
module Foo
def a; 'abc'; end
def z; 'xyz'; end
end
class Bing
use(Foo, :a, 'z')
end
x = Bing.new
p x.a
p x.z
There has to be a more elegant way to do this. What is it?
Kirk Haines