Add a method to the Error class


#1

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?


#2

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


#3

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?


#4

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


#5

Rick O. wrote:

I’d highly suggest reading the pickaxe book on this. It explains it
much better and provides diagrams…

Right. Thanks


#6

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