I have this fancy class:
Read from one and write to another.
class RWDelegator
def initialize( read, write )
@read = read
@write = write
end
def inspect
"#{@read.call.inspect}*"
end
def ==( other )
@read.call == other
end
def method_missing( meth, *args, &blk )
read = @read.call
ditto = read.dup
result = ditto.send( meth, *args, &blk )
if ditto != read
result = @write.call.send( meth, *args, &blk )
end
result
end
end
I’m can’t achieve equlity when:
a, b = 1, 1
r, w = lambda{ a }, lambda{ b }
rwd = RWDelegator.new( r, w )
rwd == a #=> true
a == rwd #=> false
Any hope?
T.
unknown wrote:
Read from one and write to another.
class RWDelegator
…
end
I’m can’t achieve equlity when:
a, b = 1, 1
r, w = lambda{ a }, lambda{ b }
rwd = RWDelegator.new( r, w )
rwd == a #=> true
a == rwd #=> false
Any hope?
T.
I get a == rwd #=> true ?
On 7/6/06, Chris H. [email protected] wrote:
I get a == rwd #=> true ?
As do I:
$ cat test.rb
class RWDelegator
def initialize( read, write )
@read = read
@write = write
end
def inspect
"#{@read.call.inspect}*"
end
def ==( other )
@read.call == other
end
def method_missing( meth, *args, &blk )
read = @read.call
ditto = read.dup
result = ditto.send( meth, *args, &blk )
if ditto != read
result = @write.call.send( meth, *args, &blk )
end
result
end
end
a, b = 1, 1
r, w = lambda{ a }, lambda{ b }
rwd = RWDelegator.new( r, w )
puts rwd == a
puts a == rwd
$ ruby -v test.rb
ruby 1.8.4 (2005-12-24) [i386-linux]
true
true
Jacob F.
Chris H. wrote:
T.
I get a == rwd #=> true ?
Ah, it’s simplified example of what I’m actually doing. So in this case
the integers auto-coerce it seems. Try:
a, b = "1", "1"
Which is probably a clue that can can be doen via #coerce, but I’m not
sure how.
T.
unknown wrote:
I get a == rwd #=> true ?
Ah, it’s simplified example of what I’m actually doing. So in this case
the integers auto-coerce it seems. Try:
a, b = "1", "1"
Which is probably a clue that can can be doen via #coerce, but I’m not
sure how.
T.
I suggest modifying your == method to:
def ==( other )
#p “#{@read.call} == #{other.inspect}”
if other.kind_of?(RWDelegator)
other == @read.call
else
@read.call == other
end
end
To compare to other objects you can:
-
write conversion methods (i.e. to_s) and than convert the RWDelegator
to the appropriate type when comparing (i.e. rwd.to_s == “1”)
-
re-write the conversion methods of the other classes to handle your
RWDelegator class appropriately:
class String
alias old== ==
def ==(other)
if other.kind_of(RWDelegator)
other == self
else
old==(other)
end
end
Cheers
Chris H. wrote:
To compare to other objects you can:
else
old==(other)
end
end
Thanks! Your suggestions gave me this idea:
class RWDelegator
def initialize( write, &read )
@read = read
@write = write
read_class = @read.call.object_class
unless read_class.method_defined?(:eq_with_rwdelegator?)
read_class.class_eval %{
def eq_with_rwdelegator?( other )
if RWDelegator === other
other == self
else
eq_without_rwdelegator?(other)
end
end
alias_method :eq_without_rwdelegator?, :==
alias_method :==, :eq_with_rwdelegator?
}
end
end
…
T.
Srinivas JONNALAGADDA wrote:
read_class.class_eval %{
end
end
…
T.
The above approach would not scale seamlessly should you have another
RWDelegator-like class.
Any suggestions to fix?
I would be interested in knowing the situation that required something
like this.
It is for method Annotations. The problem here is that annotations are
inherited. So when readin them you want to see the merged result from
the current class (receiver) up through Kernel itself. But when you are
writting to them you want to just effect the the current class. Here’s
an example::
class Y
ann :a, :foo => [1]
end
class X < Y
ann :a, :bar => [2]
end
Y.ann.a #=> #
X.ann.a #=> #
X.ann.a.foo << 2
X.ann.a #=> #
Y.ann.a #=> #
In the past, one had to do
X.ann.a.foo! << 2
for this to work. Perhaps the overhead of th RWDelegator is too much
and I should go back to the original way? Even so, it was quite a
challenge to ge the above to work.
T.
[email protected] wrote:
def eq_with_rwdelegator?( other )
end
…
T.
The above approach would not scale seamlessly should you have another
RWDelegator-like class.
I would be interested in knowing the situation that required something
like this.
JS