Forum: Ruby on Rails add a method to the Error class

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Simon.Santoro (Guest)
on 2005-11-20 22:19
(Received via mailing list)
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?
technoweenie (Guest)
on 2005-11-20 22:27
(Received via mailing list)
On 11/20/05, Simon S. <removed_email_address@domain.invalid> wrote:
>        "ciao!"
>
> 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
Simon.Santoro (Guest)
on 2005-11-20 22:35
(Received via mailing list)
Rick O. 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?
technoweenie (Guest)
on 2005-11-20 23:11
(Received via mailing list)
> 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
Simon.Santoro (Guest)
on 2005-11-20 23:31
(Received via mailing list)
Rick O. wrote:
> I'd highly suggest reading the pickaxe book on this.  It explains it
> much better and provides diagrams...

Right. Thanks
justin (Guest)
on 2005-11-21 04:01
(Received via mailing list)
Simon S. wrote:
> Rick O. 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
This topic is locked and can not be replied to.