I just tried to extract the methods defined in a class and make a mixin
of them. My code looked like this:
class Class
def mixin(*methods)
klass = self
methods.empty? and methods = klass.instance_methods(false)
m = Module.new
m.instance_eval do
methods.each do |s|
define_method(s, klass.instance_method(s))
end
end
m
end
end
class A < Array
def foo; “foo”; end
def bar; “bar”; end
end
class B
end
Mixin1 = A.mixin(:foo)
class B
include Mixin1
end
p B.new.foo
Mixin2 = A.mixin
class C
include Mixin2
end
c = C.new
p c.foo
p c.bar
It failed with a type error “bind argument must be an instance of A”. I
don’t see why it must be such an instance, because I think this should
be a job for duck typing to find out if messages fail, that are sent in
the method body. So i patched eval.c to stop complaining and it worked.
Perhaps I am missing something: But is there a reason for this check or
could it be deleted in eval.c to allow this behaviour?
–
The whole problem with the world is that fools and fanatics are always so
certain of themselves, but wiser people so full of doubts.
– Bertand Russell
Mixin1 = Array.mixin(:=)
class B
include Mixin1
end
a = B.new
a[12] = 24
Line 23 ^^^
p a
It doesn’t work - I’m getting the same error as before (in the unpatched
ruby version):
bash-2.05a$ ruby mixin.rb
mixin.rb:23:in `=': bind argument must be an instance of Array (TypeError)
from mixin.rb:23
The problem is that the = method remembers the class, that it was bound to
before, and a type error is raised.
···
On 2003-09-10 22:48:24 +0900, ts wrote:
–
The liberty of a democracy is not safe if the people tolerate the growth
of private power to a point where it becomes stronger than their
democratic State itself. That, in its essence, is Fascism – ownership of
government by an individual, by a group, or any controlling private power.
– Franklin D. Roosevelt
It doesn't work - I'm getting the same error as before (in the unpatched
ruby version):
With your *patched* version
svg% cat b.rb
#!/usr/bin/ruby -w
class Class
def mixin(*methods)
klass = self
methods.empty? and methods = klass.instance_methods(false)
m = Module.new
m.instance_eval do
methods.each do |s|
define_method(s, klass.instance_method(s))
end
end
m
end
end
Mixin1 = Array.mixin(:=)
class B
include Mixin1
end
a = B.new
a[12] = 24
p a
svg%
I am not sure. This probably happens because Array has some internal
magic that can’t be extracted (that easy). However, one could argue that
you have know what you are doing anyway if you try to do such fancy
stuff. If you’re afraid that it hurts you just don’t do it.
···
On 2003-09-11 18:54:15 +0900, ts wrote:
–
It is practically impossible to teach good programming style to students
that have had prior exposure to BASIC; as potential programmers they are
mentally mutilated beyond hope of regeneration.
– Edsger Dijkstra, How do we tell truths that might hurt?
I am not sure. This probably happens because Array has some internal
magic that can't be extracted (that easy). However, one could argue that
you have know what you are doing anyway if you try to do such fancy
What do you do with all embedded applications which run code written by
someone else ?
stuff. If you're afraid that it hurts you just don't do it.
I'm agree with you : it's best to don't apply the patch.