7

I don't understand the keywords like attr_reader or property in the following example:

class Voiture 
  attr_reader :name
  attr_writer :name
  property :id, Serial
  property :name, String
  property :completed_at, DateTime
end

How do they work? How can I create my own? Are they functions, methods?

class MyClass 
    mymagickstuff :hello
end
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
DrIDK
  • 7,642
  • 2
  • 14
  • 14
  • 6
    `attr_reader` is a method, but is built in. `property` is a method provided by a gem (e.g. ActiveRecord) using a little meta-programming to add features to a class. You *can* make your own. See my answer to a similar question here for an example: http://stackoverflow.com/questions/18742034/setting-an-instance-variable-in-a-class-scope-method/18742507#18742507 – Neil Slater Sep 27 '13 at 16:41
  • "[Why use Ruby's attr_accessor, attr_reader and attr_writer?](http://stackoverflow.com/questions/5046831/why-use-rubys-attr-accessor-attr-reader-and-attr-writer)" is a very useful answer regarding the `attr...` methods. Also, "[What is attr_accessor in Ruby?](http://stackoverflow.com/questions/4370960/what-is-attr-accessor-in-ruby?)" – the Tin Man Sep 27 '13 at 17:08

3 Answers3

2

That are just class methods. In this example has_foo adds a foo method to an instance that puts a string:

module Foo
  def has_foo(value)
    class_eval <<-END_OF_RUBY, __FILE__, __LINE__ + 1
      def foo
        puts "#{value}"
      end
    END_OF_RUBY
  end
end

class Baz
  extend Foo
  has_foo 'Hello World'
end

Baz.new.foo   # => Hello World
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
spickermann
  • 100,941
  • 9
  • 101
  • 131
0

You will want to monkey patch the class Module. That's where methods like attr_reader reside.

class Module
  def magic(args)
     puts args.inspect
  end
end

class A
  magic :hello, :hi
end
#=> [:hello, :hi]

As The Tin Man mentioned, monkey-patching base-level classes can be dangerous. Consider it like time-traveling into the past and adding something in the past. Just make sure that what you are adding isn't going to overwrite some other event or else you could come back to a Ruby script/timeline that isn't the same one you left.

Charles Caldwell
  • 16,649
  • 4
  • 40
  • 47
0

Those are class methods, you can add them to a class, or create your own class that has addition methods. In your own class:

class Voiture
  def self.my_first_class_method(*arguments)
    puts arguments
  end
end

Or to add to a class:

Voiture.class_eval do
  define_method :my_second_class_method do |*arguments|
    puts arguments
  end
end

Once such a class method is defined, you can use it like this:

class VoitureChild < Voiture

    my_first_class_method "print this"

    my_second_class_method "print this"

end

There are also ways to do this by adding modules to a class, which is often how rails does such things, such as using a Concern.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Andrew Kuklewicz
  • 10,621
  • 1
  • 34
  • 42