2015-11-17 85 views

回答

2

它們在Module中執行。見ruby-doc.org。在C中MRI的實現是例如爲attr_reader

static VALUE 
rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass) 
{ 
    int i; 

    for (i=0; i<argc; i++) { 
     rb_attr(klass, id_for_attr(argv[i]), TRUE, FALSE, TRUE); 
    } 
    return Qnil; 
} 

由於ClassModule孩子,他們在每一個類定義可用。

+0

我想知道實現的Ruby庫不紅寶石那些方法編譯器源代碼。 –

+2

@FarukHossen:這***是***「庫」(用於MRI)的實現。包含所有核心類的Ruby解釋器在C中實現。不存在Ruby編譯器。 –

+2

@FarukHossen實現是在C代碼:https://github.com/ruby/ruby/blob/20690026a7dd7622c7d824de71e337a68a293b63/object.c#L1938-L2020 –

2

attr_readerattr_writer是在Module中實現的方法。這些方法爲您創建一些其他方法。 attr_reader方法創建一個getter方法,而attr_writer創建一個setter方法。 attr_accessor方法attr_readerattr_writer

attr_readerattr_writer都接受多個參數。

的實現就是這樣

class Module 
    def my_accessor(*args) 
     my_reader(*args) 
     my_writer(*args) 
    end 
    def my_reader(*args) 
     args.each do |method_name| 
      inst_variable_name = "@#{method_name}".to_sym 
      define_method method_name do 
       instance_variable_get inst_variable_name 
      end 
     end 
    end 

    def my_writer(*args) 
     args.each do |method_name| 
      inst_variable_name = "@#{method_name}".to_sym 
      define_method "#{method_name}=" do |new_value| 
       instance_variable_set inst_variable_name, new_value 
      end 
     end 
    end 
end 
class TestMyAccessor 
    my_writer :a, :b, :c 
    my_reader :a, :b, :c 
    # my_accessor :a, :b, :c 
end 

o = TestMyAccessor.new 
puts o.a # nil 
puts o.b # nil 
puts o.C# nil 
o.a = 2 

o.b = 3 
o.c = "hello world" 

puts o.a # 2 
puts o.b # 3 
puts o.C# hello world 

注:我換成my_accessor attr_accessor,attr_reader與my_reader和attr_writer與my_writer

+1

真的很好。但是你應該清楚地表明,這與現實中的情況很相似。行爲也有差異,例如你不能'attr_reader:'x y'',而'my_reader:'x y''「工作」直到該屬性被訪問。 –