33

学习红宝石。我的印象是布尔属性应该命名如下:

my_boolean_attribute?

但是,尝试执行以下操作时出现语法错误:

class MyClass
  attr_accessor :my_boolean_attribute?

  def initialize
    :my_boolean_attribute? = false
  end
end

显然红宝石讨厌“?”。这是约定吗?我究竟做错了什么?

4

6 回答 6

46
于 2009-08-11T22:09:53.383 回答
43

快速添加“问题方法”的最简单方法是为您的阅读器方法使用别名

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end 
于 2009-08-13T02:59:25.093 回答
6

attr_accessor符号暗示变量名称是@my_boolean_attribute,所以这就是您应该设置的(不是符号)。

还有,不能用?对于变量,只是方法名称。

于 2009-08-11T22:05:09.883 回答
5

? 是方法名的约定,而不是变量。您不能使用名为 的实例变量@foo?,但是如果您愿意,可以使用名为的变量@foo并命名(手动创建的)getter 方法foo?

于 2009-08-11T22:01:28.423 回答
3

Monkey-patching 元编程——也许它可以做得更优雅,这只是一个草稿,我有一段时间没有做元编程了......

 # 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 ”或类似名称。

我所做的定义有点古怪,从某种意义上说,问号出现在原始符号中。可能更简洁的方法是避免符号名称中的问号并在方法定义期间附加它 - 应该不那么混乱。

哦,差点忘了包含强制性链接:清楚地看到元类

于 2009-08-11T22:20:49.710 回答
0

我查看了答案,虽然接受的答案是正确的,但它在课堂上引入了“额外”的噪音。我建议解决这个问题的方法是:

class Animal
  attr_writer :can_swim
  def initialize(animal_type_name)
    @can_swim = true
    @animal_type_name = animal_type_name
  end


  def can_swim?
    @can_swim
  end

  def to_s
    @animal_type_name
  end
end

dog = Animal.new('Dog in a bag')
dog.can_swim = false
puts "Can this #{dog} Swim? --- [#{dog_without_legs.can_swim? ? 'YEP!' : 'NOPE!'}]"
于 2020-01-08T17:44:28.220 回答