method_missing to define_method

M

Matt Todd

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.
 
E

Erik Veenstra

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/
 
A

A. S. Bradbury

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.

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
 
D

Dr Nic

Matt said:
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.
 
M

Matt Todd

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top