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.

···

--
Iñaki Baz Castillo

Hi --

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".

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);

  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.

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

···

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

--
Rails training from David A. Black and Ruby Power and Light:
   INTRO TO RAILS June 9-12 Berlin
   ADVANCING WITH RAILS June 16-19 Berlin
   INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!

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.

···

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

--
Iñaki Baz Castillo

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

--Ken

···

On Tue, 29 Apr 2008 18:26:39 -0500, Iñaki Baz Castillo 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.

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/