Method_missing question

Can someone complete the psuedo-code in SomeObject#method_missing for
me? Or suggest a better way of doing this? The attributes for
SomeObject are, in my application, are generated from a configuration
file.

Thanks
Joe

class SomeObject
    def initialize
        @attributes = { :x_pos => 20, :y_pos => 30, :z_pos => 40 }
    end

    def method_missing(method, *args)
        # test to see if this is a get or set method
        if method contains an =
            set(method minus the equal, args)
        else
            get(method)
        end
    end

    def get(attribute)
        @attributes[attribute]
    end

    def set(attribute, value)
        @attributes[attribute] = value
    end
end

my_obj = SomeObject.new
my_obj.x_pos = 20
my_obj.z_pos = 40

assert(20, my_obj.x_pos)
assert(40, my_obj.z_pos)

class SomeObject
     def initialize
         @attributes = { :x_pos => 20, :y_pos => 30, :z_pos => 40 }
     end

     def method_missing(meth, *args) # notice rename - don't like having vars the same as methods
         # test to see if this is a get or set method
         if meth =~ /^(.+)=$/
             set($1.intern, args)
         else
             get(meth)
         end
     end

     def get(attribute)
         @attributes[attribute]
     end

     def set(attribute, value)
         # you might also want to check at this stage that the attribute exists
         @attributes[attribute] = value
     end
end

my_obj = SomeObject.new
my_obj.x_pos = 20
my_obj.z_pos = 40

assert(20, my_obj.x_pos)
assert(40, my_obj.z_pos)

···

On Feb 3, 2005, at 11:33 AM, Joe Van Dyk wrote:

Can someone complete the psuedo-code in SomeObject#method_missing for
me? Or suggest a better way of doing this? The attributes for
SomeObject are, in my application, are generated from a configuration
file.

--
ryand-ruby@zenspider.com - Seattle.rb - http://www.zenspider.com/seattle.rb
http://blog.zenspider.com/ - http://rubyforge.org/projects/ruby2c

Can someone complete the psuedo-code in SomeObject#method_missing for
me? Or suggest a better way of doing this? The attributes for
SomeObject are, in my application, are generated from a configuration
file.

Thanks
Joe

class SomeObject
    def initialize
        @attributes = { :x_pos => 20, :y_pos => 30, :z_pos => 40 }
    end

    def method_missing(method, *args)
        # test to see if this is a get or set method
        if method contains an =
            set(method minus the equal, args)
        else
            get(method)
        end
    end

Here's what I have so far. This works, but wondering if something
better's out there.

    def method_missing(method, *args)
        puts "method missing called with #{method} and #{args}"
        
        if method.to_s =~ /^(.+)=$/
            set($1.to_sym, *args)
        else
            get(method.to_sym)
        end
    end

···

On Thu, 3 Feb 2005 11:32:53 -0800, Joe Van Dyk <joevandyk@gmail.com> wrote:

    def get(attribute)
        @attributes[attribute]
    end

    def set(attribute, value)
        @attributes[attribute] = value
    end
end

my_obj = SomeObject.new
my_obj.x_pos = 20
my_obj.z_pos = 40

assert(20, my_obj.x_pos)
assert(40, my_obj.z_pos)

"Joe Van Dyk" <joevandyk@gmail.com> schrieb im Newsbeitrag
news:c715e64050203113235bcec38@mail.gmail.com...

Can someone complete the psuedo-code in SomeObject#method_missing for
me? Or suggest a better way of doing this? The attributes for
SomeObject are, in my application, are generated from a configuration
file.

Thanks
Joe

class SomeObject
    def initialize
        @attributes = { :x_pos => 20, :y_pos => 30, :z_pos => 40 }
    end

    def method_missing(method, *args)
        # test to see if this is a get or set method
        if method contains an =
            set(method minus the equal, args)
        else
            get(method)
        end
    end

    def get(attribute)
        @attributes[attribute]
    end

    def set(attribute, value)
        @attributes[attribute] = value
    end
end

my_obj = SomeObject.new
my_obj.x_pos = 20
my_obj.z_pos = 40

assert(20, my_obj.x_pos)
assert(40, my_obj.z_pos)

Did you consider using OpenStruct?

require 'ostruct'

my_obj = OpenStruct.new
my_obj.x_pos = 20
my_obj.z_pos = 40

assert(20, my_obj.x_pos)
assert(40, my_obj.z_pos)

Kind regards

    robert

Joe Van Dyk wrote:

Can someone complete the psuedo-code in SomeObject#method_missing for
me? Or suggest a better way of doing this? The attributes for
SomeObject are, in my application, are generated from a configuration
file.

Thanks
Joe

class SomeObject
    def initialize
        @attributes = { :x_pos => 20, :y_pos => 30, :z_pos => 40 }
    end

Perhaps you could do it simpler by changing this logic? I was thinking along the lines of

def initialize()
   { :x_pos => 20, :y_pos => 30, :z_pos => 40 }.each do |key, value|
     instance_variable_set("@#{key}", value)
     class << self; self; end.send(:attr_accessor, key)
   end
end

But that won't quite work when the field set can change after initialize has been called. When you know all the keys upfront you can also move the accessors to the class definition.

That looks fine to me. I, by habit/musclememory, use intern instead of to_sym. You shouldn't need to do it for your get as method_missing should be passed a symbol in the first place.

···

On Feb 3, 2005, at 11:51 AM, Joe Van Dyk wrote:

Here's what I have so far. This works, but wondering if something
better's out there.

    def method_missing(method, *args)
        puts "method missing called with #{method} and #{args}"

        if method.to_s =~ /^(.+)=$/
            set($1.to_sym, *args)
        else
            get(method.to_sym)
        end
    end

Thanks for the input. My previous function failed on code like

assert(my_obj.x_pos == 10)

so I needed to add an

elsif method.to_s =~ /^(.+)==$/
  get($1.to_sym)

to SomeObject#method_missing.

···

On Fri, 4 Feb 2005 05:10:59 +0900, Ryan Davis <ryand@zenspider.com> wrote:

On Feb 3, 2005, at 11:51 AM, Joe Van Dyk wrote:

> Here's what I have so far. This works, but wondering if something
> better's out there.
>
> def method_missing(method, *args)
> puts "method missing called with #{method} and #{args}"
>
> if method.to_s =~ /^(.+)=$/
> set($1.to_sym, *args)
> else
> get(method.to_sym)
> end
> end

That looks fine to me. I, by habit/musclememory, use intern instead of
to_sym. You shouldn't need to do it for your get as method_missing
should be passed a symbol in the first place.