Ruby:布尔属性命名约定和使用

时间:2023-01-18 21:21:43

Learning ruby. I'm under the impression that boolean attributes should be named as follows:

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

my_boolean_attribute?

However, I get syntax errors when attempting to do the following:

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

class MyClass
  attr_accessor :my_boolean_attribute?

  def initialize
    :my_boolean_attribute? = false
  end
end

Apparently ruby is hating the "?". Is this the convention? What am I doing wrong?

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

5 个解决方案

#1


41  

Edit: three-years later; the times, they are a-changin'…

编辑:三年后;时代,他们是a-changin'......

Julik's answer is the simplest and best way to tackle the problem these days:

Julik的答案是解决这个问题的最简单,最好的方法:

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

My answer to the original question follows, for posterity…

对于后人,我对原始问题的回答如下:


The short version:

简短版本:

You can't use a question mark in the name of an instance variable.

您不能在实例变量的名称中使用问号。

The longer version:

版本较长:

Take, for example, attr_accessor :foo — it's simply conceptually a bit of syntactic sugar for the following:

以attr_accessor:foo为例 - 从概念上讲,它仅仅是以下的一些语法糖:

def foo
  @foo
end

def foo=(newfoo)
  @foo = newfoo
end

Furthermore, the question-mark suffix is mostly just a convention to indicate that the return value of a method is a boolean.

此外,问号后缀大多只是一个约定,表示方法的返回值是布尔值。

The best approximation I can make of what you're going for here…

我能在这里得到的最佳近似值...

class MyClass

  def initialize
    @awesome = true
  end

  def awesome?
    @awesome
  end

end

In this case, there may be a case to be made for using attr_accessor — after all, it may be explicit that you're working directly with a boolean attribute. Generally, I save the question-mark suffix for when I am implementing a method whose boolean return value is based on slightly more complex conditions than just the value of an attribute.

在这种情况下,可能存在使用attr_accessor的情况 - 毕竟,您可能明确表示您正在使用布尔属性。通常,我在实现一个方法时保存问号后缀,该方法的布尔返回值基于稍微复杂的条件而不仅仅是属性的值。

Cheers!

干杯!


Edit, two years later, after a recent comment:

两年后编辑,在最近的评论之后:

  1. Ruby enforces certain naming conventions. Symbols in Ruby can't have question marks. Thus invocations of :my_boolean_attribute? both will fail with a NameError. Edit: not correct, just use the quoted syntax for a symbol, e.g., :"my_attribute?"
  2. Ruby强制执行某些命名约定。 Ruby中的符号不​​能有问号。因此调用:my_boolean_attribute?两者都会因NameError而失败。编辑:不正确,只需使用符号的引用语法,例如:“my_attribute?”
  3. Symbols are immutable, attempting to assign to one will throw a SyntaxError.
  4. 符号是不可变的,尝试分配给一个将抛出一个SyntaxError。

#2


39  

The easiest way to quickly add a "question method" is to use aliasing for your reader method

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

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

#3


6  

The attr_accessor symbol implies that the variable name is @my_boolean_attribute, so that's what you should be setting (not the symbol).

attr_accessor符号表示变量名称是@my_boolean_attribute,因此您应该设置(而不是符号)。

Also, you can't use ? for variables, just method names.

另外,你不能使用?对于变量,只是方法名称。

#4


5  

? is convention for methodnames, not variables. You can't use an instance variable named @foo?, however you could use a variable named @foo and name the (manually created) getter method foo? if you wanted to.

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

#5


3  

Monkey-patching metaprogramming - maybe it can be made more elegant, this is only a quick draft, and I haven't done metaprogramming for a little while...

猴子修补元编程 - 也许它可以变得更优雅,这只是一个快速的草稿,我还没有做过一段时间的元编程...

 # 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?

With this approach, you can be DRY and get the nice questionmark too. You just might need to pick a better name than "bool_attr", like, "bool_attr_accessor" or something similar.

使用这种方法,你可以干,并获得好的问号。您可能需要选择比“bool_attr”更好的名称,例如“bool_attr_accessor”或类似名称。

The definitions that I made are a bit cranky, in a sense that the question mark is present in the original symbol. Probably a cleaner approach would be to avoid the questionmark in the symbol name and append it during the definition of the method - should be less confusing.

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

Oh, and almost forgot to include the obligatory link: Seeing metaclasses clearly

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

#1


41  

Edit: three-years later; the times, they are a-changin'…

编辑:三年后;时代,他们是a-changin'......

Julik's answer is the simplest and best way to tackle the problem these days:

Julik的答案是解决这个问题的最简单,最好的方法:

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

My answer to the original question follows, for posterity…

对于后人,我对原始问题的回答如下:


The short version:

简短版本:

You can't use a question mark in the name of an instance variable.

您不能在实例变量的名称中使用问号。

The longer version:

版本较长:

Take, for example, attr_accessor :foo — it's simply conceptually a bit of syntactic sugar for the following:

以attr_accessor:foo为例 - 从概念上讲,它仅仅是以下的一些语法糖:

def foo
  @foo
end

def foo=(newfoo)
  @foo = newfoo
end

Furthermore, the question-mark suffix is mostly just a convention to indicate that the return value of a method is a boolean.

此外,问号后缀大多只是一个约定,表示方法的返回值是布尔值。

The best approximation I can make of what you're going for here…

我能在这里得到的最佳近似值...

class MyClass

  def initialize
    @awesome = true
  end

  def awesome?
    @awesome
  end

end

In this case, there may be a case to be made for using attr_accessor — after all, it may be explicit that you're working directly with a boolean attribute. Generally, I save the question-mark suffix for when I am implementing a method whose boolean return value is based on slightly more complex conditions than just the value of an attribute.

在这种情况下,可能存在使用attr_accessor的情况 - 毕竟,您可能明确表示您正在使用布尔属性。通常,我在实现一个方法时保存问号后缀,该方法的布尔返回值基于稍微复杂的条件而不仅仅是属性的值。

Cheers!

干杯!


Edit, two years later, after a recent comment:

两年后编辑,在最近的评论之后:

  1. Ruby enforces certain naming conventions. Symbols in Ruby can't have question marks. Thus invocations of :my_boolean_attribute? both will fail with a NameError. Edit: not correct, just use the quoted syntax for a symbol, e.g., :"my_attribute?"
  2. Ruby强制执行某些命名约定。 Ruby中的符号不​​能有问号。因此调用:my_boolean_attribute?两者都会因NameError而失败。编辑:不正确,只需使用符号的引用语法,例如:“my_attribute?”
  3. Symbols are immutable, attempting to assign to one will throw a SyntaxError.
  4. 符号是不可变的,尝试分配给一个将抛出一个SyntaxError。

#2


39  

The easiest way to quickly add a "question method" is to use aliasing for your reader method

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

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

#3


6  

The attr_accessor symbol implies that the variable name is @my_boolean_attribute, so that's what you should be setting (not the symbol).

attr_accessor符号表示变量名称是@my_boolean_attribute,因此您应该设置(而不是符号)。

Also, you can't use ? for variables, just method names.

另外,你不能使用?对于变量,只是方法名称。

#4


5  

? is convention for methodnames, not variables. You can't use an instance variable named @foo?, however you could use a variable named @foo and name the (manually created) getter method foo? if you wanted to.

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

#5


3  

Monkey-patching metaprogramming - maybe it can be made more elegant, this is only a quick draft, and I haven't done metaprogramming for a little while...

猴子修补元编程 - 也许它可以变得更优雅,这只是一个快速的草稿,我还没有做过一段时间的元编程...

 # 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?

With this approach, you can be DRY and get the nice questionmark too. You just might need to pick a better name than "bool_attr", like, "bool_attr_accessor" or something similar.

使用这种方法,你可以干,并获得好的问号。您可能需要选择比“bool_attr”更好的名称,例如“bool_attr_accessor”或类似名称。

The definitions that I made are a bit cranky, in a sense that the question mark is present in the original symbol. Probably a cleaner approach would be to avoid the questionmark in the symbol name and append it during the definition of the method - should be less confusing.

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

Oh, and almost forgot to include the obligatory link: Seeing metaclasses clearly

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