Создать методы attr_reader при установке значений для соответствующих переменных экземпляра в методе initialize? - PullRequest
1 голос
/ 18 марта 2012

Я ищу способ создания соответствующих методов attr_reader при установке значений для соответствующих переменных экземпляра в методе initialize?Например, следующий код:

class SomeClass
  attr_reader :hello
  def initialize( arg)
    @hello = arg
  end
end

Я ищу способ записи следующим образом:

class SomeClass
  def initialize( arg)
    some_method_as_described_in_question( @hello, arg) 
  end
end   

Существует ли метод, выполняющий то, что я описал, во встроенном RubyКлассы и модули?

Ответы [ 3 ]

4 голосов
/ 18 марта 2012

Вы можете открыть собственный класс из метода и установить там атрибут:

class SomeClass
  def initialize(arg)
    (class << self; self; end).send(:attr_reader, :hello)
    @hello = arg
  end
end

Таким образом, собственный класс каждого экземпляра будет иметь это средство чтения атрибутов. Но на самом деле имеет смысл действовать таким образом, только если имя атрибута динамическое и может варьироваться от экземпляра к экземпляру. Если это всегда hello, я не вижу никаких недостатков, если просто определить его в классе, как ваш оригинальный блок кода.

Например, если вы динамически передаете имя атрибута, вы можете сделать это следующим образом:

class SomeClass
  def initialize(attr, arg)
    (class << self; self; end).send(:attr_reader, attr.to_sym)
    instance_variable_set("@#{attr}", arg)
  end
end

Это совместимо с Ruby 1.8. Взяв подсказку от @HenrikN в комментарии к вашему вопросу, вы можете использовать define_singleton_method в Ruby 1.9:

class SomeClass
  def initialize(attr, arg)
    define_singleton_method(attr) { instance_variable_get("@#{attr}") }
    instance_variable_set("@#{attr}", arg)
  end
end
0 голосов
/ 18 марта 2012
require 'ostruct'

p = OpenStruct.new
p.hello = 'world'
p.could_be_anything = 'nothing'
puts p.hello #=> 'world'
puts p.could_be_anything #=> 'nothing'
0 голосов
/ 18 марта 2012

Не уверен, что я понимаю вопрос, но вы можете использовать Struct, чтобы получить методы инициализатора и средства доступа:

class SomeClass < Struct.new(:hello)
end

x = SomeClass.new("yo")
puts x.hello  # "yo"
x.hello = "what up"
puts x.hello  # "what up"
...