[Rubycocoa-devel 1158] Re: Duck typing for NSArray and NSDictionary

Zurück zum Archiv-Index

Eloy Duran eloy.****@gmail*****
Sat Sep 1 23:49:59 JST 2007


Hey Satoshi-san,

I see that you've ported quite some methods in the past few weeks (was
away on holiday), which I think is great!
However, I'm wondering where's the limit? Or how far (which classes)
are you intending of taking this?

I can see that there are a number of methods which would be used a lot
of times in normal circumstances, the most commoly string, array, hash
methods etc. Obviously these benefit from being ported speedwise.
However, I think an extra dynamic solution should also be provided for
classes not deemed important enough or not yet ported. I don't know if
this should be enabled by default or that the dev should choose to
enable it so that he/she knows what's happening.

Anyhow, I think method_missing is not the right way to provide this solution.
I have looked up some code I used once to do this. Obviously it wasn't
tested for all cases and would need more work, for instance on the
arity part. But it did work for my case.
Downside of course is that any dynamically added methods to th
edelegate class after setting it up will not be available to the
class. There might be ways around this though.

class OSX::NSObject
  class << self
    def _setup_ruby_delegate_methods(to_ruby_type)
      (to_ruby_type[:to_class].instance_methods(false) -
self.instance_methods - self.objc_instance_methods).each do |mname|
        # TODO: add the method with the same arity as tge original
delegate method
        define_method(mname) do |*args|
          puts "INFO: #{self.class}##{mname}: This is a dynamically
generated delegate method. If used a lot, you could probably improve
the speed performance by porting this method over. Please see
oc_attachments.rb" if $DEBUG
          self.send(to_ruby_type[:to_method]).send(mname, *args)
        end
      end
    end
  end
end

class OSX::NSArray
  self._setup_ruby_delegate_methods :to_class => Array, :to_method => :to_a
end

arr = OSX::NSArray.arrayWithArray([1, 2, 3])
arr.first
arr.last

class OSX::NSString
  self._setup_ruby_delegate_methods :to_class => String, :to_method => :to_s
end

str = "foo".to_nsstring
str.gsub(/oo/, 'aa')

Just my 2 cents :)

Cheers,
Eloy

On 8/28/07, Satoshi Nakagawa <snaka****@infot*****> wrote:
> Hi.
>
> I did a benchmark of reference and assignment to NSArray.
> It shows method_missing is very slow.
>
>
> * Benchmarking code
>
>   #refer
>
>     ns = NSMutableArray.alloc.init
>     2000.times {|i| ns.push(i.to_s) }
>     puts Benchmark.measure {
>       1000.times {|i| a = ns[i] }
>     }
>
>     rb = []
>     2000.times {|i| rb << i.to_s }
>     puts Benchmark.measure {
>       1000.times {|i| b = rb[i] }
>     }
>
>   #assign
>
>     ns = NSMutableArray.alloc.init
>     2000.times {|i| ns.push(i.to_s) }
>     puts Benchmark.measure {
>       1000.times {|i|
>         ns[i..(i+20)] = [1,2,3,4,5,6,7,8,9,10,11,12]
>         ns[i,10] = [1,2,3,4,5,6,7,8,9,10,11,12]
>       }
>     }
>
>     rb = []
>     2000.times {|i| rb << i.to_s }
>     puts Benchmark.measure {
>       1000.times {|i|
>         rb[i..(i+20)] = [1,2,3,4,5,6,7,8,9,10,11,12]
>         rb[i,10] = [1,2,3,4,5,6,7,8,9,10,11,12]
>       }
>     }
>
>
> * Result
>
> - Ruby Array
>
>   #refer
>     0.000000   0.000000   0.000000 (  0.000681)
>   #assign
>     0.000000   0.000000   0.000000 (  0.004040)
>
> - NSArray
>
>   method_missing
>   #refer
>     7.360000   0.010000   7.370000 (  7.373584)
>   #assign
>     6.290000   0.010000   6.300000 (  6.299202)
>
>   trunk
>   #refer
>     0.030000   0.000000   0.030000 (  0.030196)
>   #assign
>     0.420000   0.000000   0.420000 (  0.421565)
>
>
>   def [](index)
>     count = self.count
>     if 0 <= index && index < count
>       objectAtIndex(index)
>     else
>       nil
>     end
>   end
>
>   #refer
>     0.020000   0.000000   0.020000 (  0.019137)
>
> --
> Satoshi Nakagawa
>
> _______________________________________________
> Rubycocoa-devel mailing list
> Rubyc****@lists*****
> http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel
>




More information about the Rubycocoa-devel mailing list
Zurück zum Archiv-Index