Created
October 9, 2009 06:24
-
-
Save tansengming/205787 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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