Рубин:Соглашение об именовании и использовании логических атрибутов

StackOverflow https://stackoverflow.com/questions/1263160

Вопрос

Изучаю ruby.У меня сложилось впечатление, что логические атрибуты должны быть названы следующим образом:

my_boolean_attribute?

Однако я получаю синтаксические ошибки при попытке выполнить следующее:

class MyClass
  attr_accessor :my_boolean_attribute?

  def initialize
    :my_boolean_attribute? = false
  end
end

Очевидно, Руби ненавидит это "?".Это и есть конвенция?Что я делаю не так?

Это было полезно?

Решение

Редактировать:три года спустя;времена, они меняются…

Ответ Юлика это самый простой и лучший способ решить проблему на сегодняшний день:

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end

Мой ответ на исходный вопрос следует для потомков…


Краткая версия:

Вы не можете использовать вопросительный знак в имени переменной экземпляра.

Более длинная версия:

Возьмем, к примеру, attr_accessor :foo - его просто концептуально немного синтаксического сахара для следующего:

def foo
  @foo
end

def foo=(newfoo)
  @foo = newfoo
end

Более того, суффикс вопросительного знака в основном является просто соглашением, указывающим, что возвращаемое значение метода является логическим.

Лучшее приближение, которое я могу сделать, к тому, чего вы здесь добиваетесь…

class MyClass

  def initialize
    @awesome = true
  end

  def awesome?
    @awesome
  end

end

В этом случае может возникнуть необходимость использовать attr_accessor — в конце концов, может быть очевидно, что вы работаете напрямую с логическим атрибутом.Обычно я сохраняю суффикс вопросительного знака, когда реализую метод, логическое возвращаемое значение которого основано на немного более сложных условиях, чем просто значение атрибута.

Ваше здоровье!


Редактировать, два года спустя, после недавнего комментария:

  1. Ruby применяет определенные соглашения об именах. Символы в Ruby не могут иметь вопросительных знаков.Таким образом, вызовы :my_boolean_attribute? оба потерпят неудачу с NameError. Редактировать:неверно, просто используйте синтаксис в кавычках для символа, например, :"my_attribute?"
  2. Символы неизменяемы, попытка назначить один из них вызовет ошибку. SyntaxError.

Другие советы

Самый простой способ быстро добавить «метод вопроса» — использовать псевдоним для метода чтения.

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end 

Тот Самый attr_accessor символ подразумевает, что имя переменной равно @my_boolean_attribute, так что это то, что вы должны устанавливать (не символ).

Кроме того, вы не можете использовать?для переменных используйте только имена методов.

?это соглашение для имен методов, а не переменных.Вы не можете использовать переменную экземпляра с именем @foo?, однако вы можете использовать переменную с именем @foo и назовите (созданный вручную) метод получения foo? если бы ты захотел.

Метапрограммирование с исправлением обезьян - возможно, его можно сделать более элегантным, это всего лишь быстрый набросок, и я какое-то время не занимался метапрограммированием...

 # inject the convenience method into the definition of the Object class
 class Object
   def Object::bool_attr(attrname)
     class_eval { define_method(attrname.to_s,
          lambda { instance_variable_get('@' + attrname.to_s.chop) }) }
     class_eval { define_method(attrname.to_s.chop+"=",
          lambda { |x| instance_variable_set('@'+attrname.to_s.chop, x) }) }
   end
 end

 ### somewhere later

 class MyClass

   bool_attr :my_boolean_attribute?

   def initialize
     @my_boolean_attribute = true
   end
 end

 # yet even more later

 foo = MyClass.new
 bar = MyClass.new

 foo.my_boolean_attribute = 1
 puts foo.my_boolean_attribute?
 puts bar.my_boolean_attribute?

При таком подходе вы можете быть СУХИМ и получить красивый вопросительный знак.Возможно, вам просто придется выбрать имя получше, чем "bool_attr", нравиться, "bool_attr_accessor"или что-то подобное.

Определения, которые я дал, немного странные, в том смысле, что в исходном символе присутствует вопросительный знак.Вероятно, более чистым подходом было бы избежать вопросительного знака в имени символа и добавить его во время определения метода - это должно вызвать меньшую путаницу.

Да, и чуть не забыл включить обязательную ссылку: Ясно видеть метаклассы

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top