Method_missing to define_method

Given the circumstance that you don’t want to explicitly predefine
your methods for properties, etc, but that you’re certain your
parameters won’t somehow change to affect your design, would it be
beneficial to have method_missing define the method so that
method_missing doesn’t have to be called in case the property special
method is called again?

For instance…

class Person
@attributes = {}
def initialize attributes
@attributes.merge! attributes
end
def method_missing name
if @attributes.has_key? name
class_eval do
define_method(name) do |name|
@attributes[name]
end
end
else
# other magic
end
end
end

So, if I do…

p = Person.new { :name => “Papa”, :age => 66, :phone => “404-932-3955” }

the first time I ask for…

p.age

the method :age is created. And the next time I call it, then it just
executes the method I juist created.

So, the point in all of this (and in not using attribute accessors and
the like) is to find out if it makes sense to dynamically define
methods for accessing it on use, as opposed to by default? Is there a
real benefit? Would it just make more sense to keep using
method_missing ?

And, consider that this example is very simple, but what if there are
more advanced methods having to be created for attributes or
what-have-you (such as Person#find_by_foo_and_bar)?

Just trying to see what the community believes to be a better
practice! (Despite the recent argument against best practices.)

M.T.

class Person
@attributes = {}

This is not going to work… Well, it is going to work, but it
doesn’t do what you expected (I suppose)… You’re referring to
the instance variable of the class, which isn’t the same has
the instance variable of an instance of the class.

def initialize attributes
@attributes.merge! attributes
end

Because of the previous error, you’re calling merge! of nil…
Why not “@attributes = attributes”, as usual? You usually
initialize an object only once, anyway.

def method_missing name
if @attributes.has_key? name
class_eval do

     Object#.class_eval ???
     define_method(name) do |name|
       define_method(name) do
       @attributes[name]
     end
   end
     self.send(name)
 else
   # other magic
 end

end
end

And, consider that this example is very simple,

… but it doesn’t work… ;]

gegroet,
Erik V. - http://www.erikveen.dds.nl/

On Monday 07 August 2006 04:07, Matt T. wrote:

@attributes = {}
else

p.age

the method :age is created. And the next time I call it, then it just
executes the method I juist created.

Have you seen OpenStruct in the standard library?

require ‘ostruct’
p = OpenStruct.new({ :name => “Papa”, :age => 66, :phone =>
“404-932-3955” })

You can add new fields after object creation, p.occupation=“Doctor”.

I’m also curious as to whether there’s any advantage to defining methods
(as
OpenStruct does) vs just looking up hash keys in method_missing.

Alex

OK: hopefully they chose the better performer of the two!

I’ll definitely check out the OpenStruct. I think I definitely missed
out on the struct goodness when I learned C++ those few years ago. I
see Mauricio using it a good bit in his code, so it’s been tickling my
curiosity for some time.

Thanks for the comments.

M.T.

Matt T. wrote:

Given the circumstance that you don’t want to explicitly predefine
your methods for properties, etc, but that you’re certain your
parameters won’t somehow change to affect your design, would it be
beneficial to have method_missing define the method so that
method_missing doesn’t have to be called in case the property special
method is called again?

Have a look in the ActiveRecord gem - it does a similar thing.