[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

method_missing question

Joe Van Dyk

2/3/2005 7:33:00 PM

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)


6 Answers

Ryan Davis

2/3/2005 7:47:00 PM

0


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.

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)
--
ryand-ruby@zenspider.com - Seattle.rb -
http://www.zenspider.com/...
http://blog.zens... - http://rubyforge.org/proje...



Joe Van Dyk

2/3/2005 7:51:00 PM

0

On Thu, 3 Feb 2005 11:32:53 -0800, Joe Van Dyk <joevandyk@gmail.com> 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
>
> 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

>
> 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)
>


Ryan Davis

2/3/2005 8:11:00 PM

0


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.



Joe Van Dyk

2/4/2005 1:34:00 AM

0

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.


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.


Robert Klemme

2/4/2005 9:40:00 AM

0


"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

Florian Gross

2/4/2005 3:25:00 PM

0

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.