サーチ…


備考

演算子はメソッドです

ほとんどの事業者は、実際にはメソッドなので、 x + y呼び出している+方法x引数とy書き込まれる、 x.+(y)与えられた演算子の意味的意味を持つ独自のメソッドを書く場合は、そのクラスにバリアントを実装できます。

愚かな例として:

# A class that lets you operate on numbers by name.
class NamedInteger
  name_to_value = { 'one' => 1, 'two' => 2, ... }

  # define the plus method
  def + (left_addend, right_addend)
    name_to_value(left_addend) + name_to_value(right_addend)
  end

  ...
end

&&and||を使用する場合対or

ブール値を表現するには、 && and 、および|| 2つの方法があります。またはor -彼らは常にではないが、多くの場合、交換可能です。これらを「文字」と「単語」の変種と呼んでいます。

文字バリアントの優先順位が高くなり、より複雑なステートメントでかっこの必要性が減り、予期しないエラーを回避できます。

単語バリエーションは、もともとブール演算ではなくコントロールフロー演算子として意図されていました。つまり、連鎖メソッド文で使用するように設計されています。

raise 'an error' and return

ブール演算子として使用することはできますが、優先順位を低くすると予測できません。

第2に、多くのRubyistsは、x.nilなどのブール式( trueまたはfalseと評価される式)を作成するときに文字の変形を好みx.nil? || x.empty? 。一方、 一連のメソッドが評価されている場合には、バリアントが優先され、失敗する可能性があります。たとえば、失敗時にnilを返すメソッドにvariantという単語を使用する一般的なイディオムは次のようになります。

def deliver_email
  # If the first fails, try the backup, and if that works, all good
  deliver_by_primary or deliver_by_backup and return
  # error handling code
end

演算子の優先順位とメソッド

最高から最低まで、これはRubyの優先順位テーブルです。高い優先順位の操作は、低い優先順位の操作の前に行われます。

╔═══════════════════════╦════════════════════════════════════════╦═════════╗
║ Operators             ║                 Operations             ║ Method? ║
╠═══════════════════════╬════════════════════════════════════════╬═════════╣
║ .                     ║ Method call (e.g. foo.bar)             ║         ║
║ []  []=               ║ Bracket Lookup, Bracket Set            ║    ✓¹   ║
║ ! ~ +                 ║ Boolean NOT, complement, unary plus    ║    ✓²   ║
║ **                    ║ Exponentiation                         ║    ✓    ║
║ -                     ║ Unary minus                            ║    ✓²   ║
║ * / %                 ║ Multiplication, division, modulo       ║    ✓    ║
║ + -                   ║ Addition, subtraction                  ║    ✓    ║
║ << >>                 ║ Bitwise shift                          ║    ✓    ║
║ &                     ║ Bitwise AND                            ║    ✓    ║
║ | ^                   ║ Bitwise OR, Bitwise XOR                ║    ✓    ║
║ < <= >= >             ║ Comparison                             ║    ✓    ║
║ <=> == != === =~ !~   ║ Equality, pattern matching, comparison ║    ✓³   ║
║ &&                    ║ Boolean AND                            ║         ║
║ ||                    ║ Boolean OR                             ║         ║
║ .. ...                ║ Inclusive range, Exclusive range       ║         ║
║ ? :                   ║ Ternary operator                       ║         ║
║ rescue                ║ Modifier rescue                        ║         ║
║ = += -=               ║ Assignments                            ║         ║
║ defined?              ║ Defined operator                       ║         ║
║ not                   ║ Boolean NOT                            ║         ║
║ or and                ║ Boolean OR, Boolean AND                ║         ║
║ if unless while until ║ Modifier if, unless, while, until      ║         ║
║ { }                   ║ Block with braces                      ║         ║
║ do end                ║ Block with do end                      ║         ║
╚═══════════════════════╩════════════════════════════════════════╩═════════╝

Unary +とunary - は+obj-objまたは-(some_expression)です。

Modifier-if、modifier-unlessなどは、これらのキーワードの修飾語バージョン用です。たとえば、これは式でない限り修飾語です:

a += 1 unless a.zero?

✓の演算子はメソッドとして定義できます。ほとんどのメソッドの名前は、演算子の名前と同じです(例:

class Foo
  def **(x)
    puts "Raising to the power of #{x}"
  end
  def <<(y)
    puts "Shifting left by #{y}"
  end
  def !
    puts "Boolean negation"
  end
end

Foo.new ** 2     #=> "Raising to the power of 2"
Foo.new << 3     #=> "Shifting left by 3"
!Foo.new         #=> "Boolean negation"

¹Bracket LookupとBracket Setのメソッド( [][]= )は、名前の後に引数が定義されています。

class Foo
  def [](x)
    puts "Looking up item #{x}"
  end
  def []=(x,y)
    puts "Setting item #{x} to #{y}"
  end
end

f = Foo.new
f[:cats] = 42    #=> "Setting item cats to 42"
f[17]            #=> "Looking up item 17"

² "単項プラス"と "単項マイナス"演算子は、 +@-@という名前のメソッドとして定義されています

class Foo
  def -@
    puts "unary minus"
  end
  def +@
    puts "unary plus"
  end
end

f = Foo.new
+f               #=> "unary plus"
-f               #=> "unary minus"

³初期のRubyでは、不等式演算子!=と不一致演算子!~をメソッドとして定義できませんでした。代わりに、対応する等価演算子==または一致する演算子=~メソッドが呼び出され、そのメソッドの結果はRubyによって論理反転されました。

独自の!=または!~演算子を定義していない場合、上記の動作は依然として真です。しかし、Ruby 1.9.1では、これら2つの演算子をメソッドとして定義することもできます。

class Foo
  def ==(x)
    puts "checking for EQUALITY with #{x}, returning false"
    false
  end
end

f = Foo.new
x = (f == 42)    #=> "checking for EQUALITY with 42, returning false"
puts x           #=> "false"
x = (f != 42)    #=> "checking for EQUALITY with 42, returning false"
puts x           #=> "true"

class Foo
  def !=(x)
    puts "Checking for INequality with #{x}"
  end
end

f != 42          #=> "checking for INequality with 42"

大文字小文字の等価演算子(===)

トリプルイコールとも呼ばれます。

この演算子は等価性をテストするのではなく、右のオペランドが左のオペランドとのIS A関係にあるかどうかをテストします。このように、一般的な名前のケースの等価演算子は誤解を招きます。

このように答えが記述されているので、 a === bを表現a === b最善の方法は、「もしa === bと書かれa引出しがあれば、 bを入れることは理にかなっていますか?言い換えれば、集合aはメンバーb含むか?

例( ソース

(1..5) === 3            # => true
(1..5) === 6            # => false

Integer === 42          # => true
Integer === 'fourtytwo' # => false

/ell/ === 'Hello'       # => true
/ell/ === 'Foobar'      # => false

オーバーライドするクラス===

多くのクラスは、case文で意味のあるセマンティクスを提供するために===をオーバーライドします。それらの一部は次のとおりです。

╔═════════════════╦════════════════════╗
║      Class      ║     Synonym for    ║
╠═════════════════╬════════════════════╣
║ Array           ║ ==                 ║
║                 ║                    ║
║ Date            ║ ==                 ║
║                 ║                    ║
║ Module          ║ is_a?              ║
║                 ║                    ║
║ Object          ║ ==                 ║
║                 ║                    ║
║ Range           ║ include?           ║
║                 ║                    ║
║ Regexp          ║ =~                 ║
║                 ║                    ║
║ String          ║ ==                 ║
╚═════════════════╩════════════════════╝

推奨される方法

ケース等価演算子===明示的な使用は避けるべきです。それは平等をテストするのではなく、むしろ包含するので、その使用は混乱する可能性があります。シノニムメソッドを代わりに使用すると、コードがわかりやすくなります。

# Bad
Integer === 42
(1..5) === 3
/ell/ === 'Hello'

# Good, uses synonym method
42.is_a?(Integer)
(1..5).include?(3)
/ell/ =~ 'Hello'

セーフナビゲーションオペレータ

Ruby 2.3.0は安全なナビゲーション演算子 &.追加しました&. 。この演算子は、条件文のobject && object.property && object.property.methodパラダイムを短縮することを目的としています。

たとえば、 addressプロパティを持つHouseオブジェクトがあり、そのaddressからstreet_nameを検索したいとしaddress 。これを古いRubyのバージョンで無限にするのを避けるために安全にプログラムするには、次のようなコードを使用します。

if house && house.address && house.address.street_name
  house.address.street_name
end

安全なナビゲーションオペレータは、この状態を短くします。代わりに、次のように書くことができます。

if house&.address&.street_name
  house.address.street_name
end

あぶない:
安全なナビゲーション演算子は、連結された条件と全く同じ動作をしません。連鎖条件(最初の例)を使用すると、たとえばaddressfalse場合、 ifブロックは実行されません。安全なナビゲーション演算子は、 nil値のみを認識しますが、 falseなどの値を許可します。 addressfalse場合、SNOを使用するとエラーが発生します。

house&.address&.street_name
# => undefined method `address' for false:FalseClass


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow