[MacRuby-devel] How do I subclass Obj-C classes in MacRuby?

Thibault Martin-Lagardette thibault.ml at gmail.com
Wed May 5 12:14:24 PDT 2010


Hi!

What you can do is a "factory" just like this:

module OpenDirectory
    class Node < ODNode
        def self.create(config = { :node_name => "/Local/Default" })
            if config[:node_name].eql? "/Local/Default"
                session = ODSession.defaultSession
            else
                session = ODSession.sessionWithOptions config[:session_options], error:nil
            end
            return self.nodeWithSession session, name:config[:node_name], error:nil
        end
        
        def initWithSession(session, name:name, error:err)
            if super
                @session = session
                self
            end
        end
    end
end

And then call:

    local_node = OpenDirectory::Node.create
    remote_node = OpenDirectory::Node.create proxy_config

And then you can pass these nodes directly to the OD methods :-)

You can also do a more Cocoa-ish way:

        def self.nodeWithConfig(config)
            config ||= { :node_name => "/Local/Default" }
            if config[:node_name].eql? "/Local/Default"
                session = ODSession.defaultSession
            else
                session = ODSession.sessionWithOptions config[:session_options], error:nil
            end
            return self.nodeWithSession session, name:config[:node_name], error:nil
        end

Then you can OpenDirectory::Node.nodeWithConfig(nil) or OpenDirectory::Node.nodeWithConfig(proxy_config).
You could even just call OpenDirectory::Node.nodeWithConfig(config), whether it's a proxy config or nothing :-)

Hope that helps!

-- 
Thibault Martin-Lagardette



On May 5, 2010, at 00:49, russell muetzelfeldt wrote:

>> From: Thibault Martin-Lagardette <thibault.ml at gmail.com>
>> 
>> Hi!
>> 
>> I believe the problem is that you were overriding the wrong init method. Here is what I changed to your code to make it work:
>> 
>> class MyNode < ODNode
>>   def initWithSession(session, name:name, error:err)
>>       if super
>>           @session = session
>>           self
>>       end
>>   end
>> end
>> 
>> session = ODSession.defaultSession
>> node = MyNode.nodeWithSession session, name: "/Local/Default", error: nil
>> 
>> I override initWithSession:name:error instead of init, and created a "MyNode" object the exact same way I would have created an ODNode :-)
>> The results were, I believe, what you would expect:
> 
> 
> 
> Thanks, but unfortunately that doesn't actually help - there's no difference in use between that and not wrapping the object init... For example, what I'm doing currently is this -
> 
> module OpenDirectory
>  class Node
>    attr_reader :node
>    def initialize config = { :node_name => "/Local/Default" }
>      if config[:node_name].eql? "/Local/Default"
>        @session = ODSession.defaultSession
>      else
>        @session = ODSession.sessionWithOptions config[:session_options], error:nil
>      end
>      @node = ODNode.nodeWithSession @session, name:config[:node_name], error:nil
>    end
>  end
> end
> 
> so I can either
> 
> local_node = OpenDirectory::Node.new
> 
> or
> 
> remote_node = OpenDirectory::Node.new proxy_config
> 
> where proxy_config is a hash containing info for a DS remote connection to our directory master. I then access the ODNode as either local_node.node or remote_node.node where required. What I want to be able to do is just use local_node or remote_node as if they were ODNode objects (or subclasses of ODNode) to remove the ruby proxying wrapper around the core Obj-C objects, but still hide the ugliness of OpenDirectory behind some simpler Model style wrappers.
> 
> (I hope that makes sense)
> 
> cheers
> 
> Russell
> 
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel



More information about the MacRuby-devel mailing list