Skip to content

Instantly share code, notes, and snippets.

@tansengming
Created October 9, 2009 06:24
Show Gist options
  • Select an option

  • Save tansengming/205787 to your computer and use it in GitHub Desktop.

Select an option

Save tansengming/205787 to your computer and use it in GitHub Desktop.
# How to build dynamic instance methods for classes.
# First define a method creator (i.e. attribute_accessor below) that
# loops through your params to create new methods.
# Via: http://codeshooter.wordpress.com/2009/06/04/understanding-class_eval-module_eval-and-instance_eval/
Object.class_eval do
class < < self
def attribute_accessor( *attribute_names )
attribute_names.each do |attribute_name|
class_eval %Q?
def #{attribute_name}
@#{attribute_name}
end
def #{attribute_name}=( new_value )
@#{attribute_name} = new_value
end
?
end
end
end
end
class Dog
attribute_accessor :name
end
dog = Dog.new
dog.name = 'Fido'
other_dog = Dog.new
other_dog.name = 'Dido'
puts dog.name
puts other_dog.name
# You can also do it with define_method, which appears to be a fancier way
# of doing class_eval
# via: http://www.vitarara.org/cms/ruby_metaprogamming_declaratively_adding_methods_to_a_class
class Talker
def self.say(*args)
puts "Inside self.say"
puts "self = #{self}"
args.each do |arg|
method_name = ("say_" + arg.to_s).to_sym
send :define_method, method_name do
puts arg
end
end
end
end
class MyTalker < Talker
say :hello
end
m = MyTalker.new
m.say_hello
# The difference between class_eval and instance_eval
# via http://blog.jayfields.com/2007/03/ruby-instanceeval-and-classeval-method.html
Foo = Class.new
Foo.class_eval do
def bar
"bar"
end
end
Foo.instance_eval do
def baz
"baz"
end
end
Foo.bar #=> undefined method ‘bar’ for Foo:Class
Foo.new.bar #=> "bar"
Foo.baz #=> "baz"
Foo.new.baz #=> undefined method ‘baz’ for #<Foo:0x7dce8>
# Also here's a set of guidelines
# * instance_eval with a proc for class, instance or singleton evaluation
# * instance_eval for changing proc bindings
# * define_method for converting procs into methods
# * def for everything else
# * eval when you really know you need it
# via http://www.mathewabonyi.com/articles/2007/01/11/surprise-10min-benchmark-eval-class_eval-instance_eval-define_method-bind
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment