Hello all! I am trying to write a plugin, and I would like to add a method to the ActiveRecord::Errors class: module Simon def self.included(base) base.extend(ClassMethods) end module ClassMethods def hello "ciao!" end end end ActiveRecord::Errors.class_eval do include Simon end but when i try to call it from my controller: @stuff = @person.errors.hello I get undefined method `hello'' for #<ActiveRecord::Errors:0xb7888df4> Why?
On 11/20/05, Simon Santoro <Simon.Santoro-Syd3ARw+vPY@public.gmane.org> wrote:> Hello all! > I am trying to write a plugin, and I would like to add a method to the > ActiveRecord::Errors class: > > module Simon > def self.included(base) > base.extend(ClassMethods) > end > module ClassMethods > def hello > "ciao!" > end > end > end > > ActiveRecord::Errors.class_eval do > include Simon > end > > but when i try to call it from my controller: > @stuff = @person.errors.hello > > I get > undefined method `hello'' for #<ActiveRecord::Errors:0xb7888df4> > > Why?Because you''re trying to add a class method to Errors and then call an instance method. Try putting hello() inside Simon. -- rick http://techno-weenie.net
Rick Olson wrote:> Because you''re trying to add a class method to Errors and then call an > instance method. Try putting hello() inside Simon.Thanks, it works. But I did not understand it... If I add the method to the class, will it not become an instance method once I create an instance of that class? If not, what are class_eval, module_eval, and instance_eval supposed to do?
> Thanks, it works. But I did not understand it... > If I add the method to the class, will it not become an instance method > once I create an instance of that class? If not, what are class_eval, > module_eval, and instance_eval supposed to do?class_eval and module_eval are aliases: http://ruby-doc.org/core/classes/Module.html#M000694 instance_eval: http://ruby-doc.org/core/classes/Object.html#M001000 Anytime you define methods in a class, they''re accessed as instance methods. When you do: class Foo def self.bar end end You''re adding a method to the singleton class, so the method is available like this: Foo.bar Remember that Foo is just an instance object of Class. I''d highly suggest reading the pickaxe book on this. It explains it much better and provides diagrams... -- rick http://techno-weenie.net
Rick Olson wrote:> I''d highly suggest reading the pickaxe book on this. It explains it > much better and provides diagrams...Right. Thanks
Simon Santoro wrote:> Rick Olson wrote: > >> Because you''re trying to add a class method to Errors and then call an >> instance method. Try putting hello() inside Simon. > > > Thanks, it works. But I did not understand it... > If I add the method to the class, will it not become an instance method > once I create an instance of that class? If not, what are class_eval, > module_eval, and instance_eval supposed to do?If you just want to add a hello method to ActiveRecord::Errors, all you need to do is ''re-open'' the class in your own code and add the method: class ActiveRecord::Errors def hello ''hi'' end end Try something similar in irb: C:\Documents and Settings\Justin>irb irb(main):001:0> class Foo irb(main):002:1> def hello irb(main):003:2> ''hi'' irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> f = Foo.new => #<Foo:0x2cfa7b8> irb(main):007:0> f.hello => "hi" irb(main):008:0> class Foo irb(main):009:1> def bye irb(main):010:2> ''ciao'' irb(main):011:2> end irb(main):012:1> end => nil irb(main):013:0> f.hello => "hi" irb(main):014:0> f.bye => "ciao" irb(main):015:0> (notice that the existing instance, f, gets the new method) regards Justin