web-dev-qa-db-ja.com

Ruby:ブール属性の命名規則と使用

Rubyを学ぶ。ブール属性には次のような名前を付ける必要があるという印象を受けています。

my_boolean_attribute?

ただし、次のことを実行しようとすると、構文エラーが発生します。

class MyClass
  attr_accessor :my_boolean_attribute?

  def initialize
    :my_boolean_attribute? = false
  end
end

どうやらRubyは「?」を嫌っています。これは慣例ですか?私は何が間違っているのですか?

32
Dane O'Connor

編集:3年後;時代は変る…

ジュリックの答え は、最近の問題に取り組むための最も簡単で最良の方法です。

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を使用する場合があります—結局のところ、ブール属性を直接操作していることが明示されている可能性があります。一般に、ブール値の戻り値が属性の値よりも少し複雑な条件に基づいているメソッドを実装する場合に備えて、疑問符の接尾辞を保存します。

乾杯!


2年後、最近のコメントの後で編集:

  1. Rubyは特定の命名規則を適用します。 Rubyのシンボルには疑問符を付けることはできません。したがって、:my_boolean_attribute?の呼び出しは両方ともNameErrorで失敗します。 編集:正しくありません。記号には引用符で囲まれた構文を使用してください。例::"my_attribute?"
  2. シンボルは不変であり、シンボルに割り当てようとするとSyntaxErrorがスローされます。
42
Nick Zadrozny

「質問メソッド」をすばやく追加する最も簡単な方法は、リーダーメソッドにエイリアシングを使用することです。

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

attr_accessor記号は、変数名が@my_boolean_attributeであることを意味するため、(記号ではなく)設定する必要があります。

また、使用できませんか?変数の場合は、メソッド名のみ。

6
Platinum Azure

?はメソッド名の規則であり、変数ではありません。 @foo?という名前のインスタンス変数を使用することはできませんが、必要に応じて@fooという名前の変数を使用し、(手動で作成した)getterメソッドにfoo?という名前を付けることができます。

5
sepp2k

モンキーパッチのメタプログラミング-もっとエレガントにすることができるかもしれませんが、これは簡単なドラフトにすぎません。しばらくの間、メタプログラミングを行っていません...

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

このアプローチでは、DRYになり、Niceの質問マークも取得できます。 "bool_attr"よりも適切な名前を選択する必要があるかもしれません。 「bool_attr_accessor」など。

私が作成した定義は、元のシンボルに疑問符が存在するという意味で、少し不格好です。おそらく、よりクリーンなアプローチは、シンボル名の疑問符を避け、メソッドの定義中にそれを追加することです-混乱を少なくする必要があります。

ああ、そして義務的なリンクを含めるのをほとんど忘れていました: メタクラスをはっきりと見る

3
Andrew Y