S
Sam Roberts
I want to make an object that behaves like another object would, if that
object had had it's #each method redefined.
I can do this with extend(), but that permanently damages the object.
I can do it with delegate/method_missing, except I need to reimplement
every method of the delegatee, which sucks.
I could do this in prototype based languages, where you can effectively
create a new object that behaves like another object with a few differences,
but don't see a way in an OO language like ruby.
Below is an example of what I want to do, implemented with extend.
But it has a problem, it modifies the target object, but I may want
to create mutiple delegates to the
target, each with a different set of "views", that behave like the
target object would if it
had its #each method redefined.
Btw, what I'm actually doing is I have a calendar object, and I want
to create various views
of the calendar, ones including events but not todos, ones that appear
to only have
components that occur in a particular period, etc.
class Base
include Enumerable
def initialize(ary)
@ary = ary.to_a
end
def each
@ary.each{|a| yield a}
end
def show
inject("show: ") {|accum, o| accum + o.to_s + ","}
end
end
module Negate
def each(&block)
super do |a|
yield -a
end
end
end
module Add10
def each(&block)
super do |a|
yield a+10
end
end
end
o = Base.new(1..3)
o.extend Negate.dup
o.extend Add10
o.extend Negate.dup
o.each {|_| puts _ }
puts o.show
object had had it's #each method redefined.
I can do this with extend(), but that permanently damages the object.
I can do it with delegate/method_missing, except I need to reimplement
every method of the delegatee, which sucks.
I could do this in prototype based languages, where you can effectively
create a new object that behaves like another object with a few differences,
but don't see a way in an OO language like ruby.
Below is an example of what I want to do, implemented with extend.
But it has a problem, it modifies the target object, but I may want
to create mutiple delegates to the
target, each with a different set of "views", that behave like the
target object would if it
had its #each method redefined.
Btw, what I'm actually doing is I have a calendar object, and I want
to create various views
of the calendar, ones including events but not todos, ones that appear
to only have
components that occur in a particular period, etc.
class Base
include Enumerable
def initialize(ary)
@ary = ary.to_a
end
def each
@ary.each{|a| yield a}
end
def show
inject("show: ") {|accum, o| accum + o.to_s + ","}
end
end
module Negate
def each(&block)
super do |a|
yield -a
end
end
end
module Add10
def each(&block)
super do |a|
yield a+10
end
end
end
o = Base.new(1..3)
o.extend Negate.dup
o.extend Add10
o.extend Negate.dup
o.each {|_| puts _ }
puts o.show