From: Lars Ticot Date: 2007-10-03T02:33:15+09:00 Subject: Re: canonical Array#append to hang hook Robert Klemme wrote: > 2007/10/2, Lars Ticot : >> To Robert Klemme: >> >> Sure I can do this but this way I lose every benefit of inheritance! And >> I'll have to rewrite "accesor" function to access function to the >> instance variable array. That is not very DRY. > > Actually the only real difference is object identity IMHO. Right for me > As has been > demonstrated there are easy to use tools that make delegation of > method invocations to the real Array really simple. Right too. But they induced over cost (during coding time and execution time) > If you provide more insight into your use case then maybe even more / > better / easier solutions will come up. It's a work at really pre alpha stage (actually I am just starting to think about how to do things). It's a kind of spreadsheet that works by column. That should approximately look like class Cell # represent the content of a cell # define some useful functions: format, is_number?,.... end class Column # represent the column as an array of Cell. end > I am convinced that it is a > bad idea to inherit Array most of the time similarly to it being a bad > idea to inherit java.util.HashMap. To continue on my example, I want to check if cells that I add on my column are number (just an example). Two possibilities: - if Column inherit from Array I'll have to do something like in my first example. - if Column does not inherit from Array it will have to delegate Array's function that I need (almost all function in Array)and the delegation has a cost (see example at the end). Moreover, what if I want to use a lib that don't rely only on duck typing and use some crapy things like this? def do_something(obj) if obj.class == Array then ... else ... end So the identity of object *is* important in some (bad?) situation. As an example, Gtk lib (and probably others) does such things (I'll post something on this and multiple inheritance in some time). My column *is* an array. So I think it's pretty clear that it should be derived from Array. Thanks Here is a quick and dirty test I made to see cost of delegating. Suprisingly, delegating and forwarding are really slow. As slow as using the method_missing (without error test). I would expect them to be as quick as the "indirect" (class C) method. require 'delegate' require 'forwardable' require 'benchmark' include Benchmark class A def hello end end class B < A end class C def initialize @a = A.new end def hello @a.hello end end class D < DelegateClass(A) def initialize a = A.new super(a) end end class E extend Forwardable def_delegator(:@a, :hello, :hello) def initialize @a=A.new end end class F def initialize @a=A.new end def method_missing(name, *args, &block) @a.send(name, *args, &block) end end a = A.new b = B.new c = C.new d = D.new e = E.new f = F.new m=100000 # My computer is an old k6-400 so you probably have to increase this! bm(10) do |x| x.report("direct ") { m.times{a.hello } } x.report("inherit ") { m.times{b.hello } } x.report("indirect") { m.times{c.hello } } x.report("delegate") { m.times{d.hello } } x.report("forward ") { m.times{e.hello } } x.report("missing ") { m.times{f.hello } } end -- Posted via http://www.ruby-forum.com/.