Where and how is defined "attr_accessor"?

Hi, I’ve done some custom “field_accessor” (similar to “attr_accessor”
but
with some neccessary difference). It works perfectly if I
defined “field_accessor” in the same class:

class Header
def self.field_accessor(name)
module_eval %{ def #{name}() … end }
end
end

class From < Header
field_accessor :user, :domain
end

But I’d like to have field_accessor definition out of “Header” class,
maybe in
a module but don’t get it working. If I do:

module FieldAccessor
module_eval %{ def #{name}() … end }
end

class From
include FieldAccessor
field_accessor :user, :domain
end

Then I get:
NoMethodError: undefined method `field_accessor’ for From:Class

Later I’ve tryed with the following and it seems to work:

module FieldAccessor
module_eval %{ def #{name}() … end }
# It also works with “class_eval”.
end

class From
extend FieldAccessor
field_accessor :user, :domain
end

So, while I was writting this mail I found the solution, but would like
to
know if it’s the correct way. Thanks a lot.

Hi –

On Wed, 30 Apr 2008, Iñaki Baz C. wrote:

class From < Header

Later I’ve tryed with the following and it seems to work:

module FieldAccessor
module_eval %{ def #{name}() … end }
# It also works with “class_eval”.

module_eval and class_eval are the same method. Here’s where those two
names are bound to the method:

rb_define_method(rb_cModule, “module_eval”, rb_mod_module_eval, -1);
rb_define_method(rb_cModule, “class_eval”, rb_mod_module_eval, -1);

know if it’s the correct way. Thanks a lot.
The last two definitions of FieldAccessor look wrong; you haven’t
defined the field_accessor method. But assuming that you correct that,
then yes, extending your class is the best way.

To answer the question in your subject line: attr_accessor is an
instance method of Module. That’s why all modules and classes can call
it. You could add field_accessor to Module, but extend is cleaner.

David

El Miércoles, 30 de Abril de 2008, David A. Black escribió:

The last two definitions of FieldAccessor look wrong; you haven’t
defined the field_accessor method. But assuming that you correct that,
then yes, extending your class is the best way.

Yes, sorry, what I did is:

    module FieldAccessor
def self.field_accessor(name)
              module_eval %{ def #{name}() .... end }
              # It also works with "class_eval".
end
    end

    class From
            extend FieldAccessor
            field_accessor :user, :domain
    end

To answer the question in your subject line: attr_accessor is an
instance method of Module. That’s why all modules and classes can call
it. You could add field_accessor to Module, but extend is cleaner.

Nice to know, so I was in the good way :wink:

Thanks a lot for your help.

On Tue, 29 Apr 2008 18:26:39 -0500, Iñaki Baz C. wrote:

El Miércoles, 30 de Abril de 2008, David A. Black escribió:

The last two definitions of FieldAccessor look wrong; you haven’t
defined the field_accessor method. But assuming that you correct that,
then yes, extending your class is the best way.

Another reasonable place is in class Module. See Ruby Q. #67:
Metakoans, which involved creating an attr_accessor like method.
http://www.rubyquiz.com/quiz67.html

–Ken

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs