What's the nature of “property” in a Ruby clas

2020-04-07 04:40发布

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

3条回答
成全新的幸福
2楼-- · 2020-04-07 04:57

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.

查看更多
在下西门庆
3楼-- · 2020-04-07 05:04

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.

查看更多
混吃等死
4楼-- · 2020-04-07 05:11

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
查看更多
登录 后发表回答