Ruby Language
演算子
サーチ…
備考
演算子はメソッドです
ほとんどの事業者は、実際にはメソッドなので、 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
あぶない:
安全なナビゲーション演算子は、連結された条件と全く同じ動作をしません。連鎖条件(最初の例)を使用すると、たとえばaddress
がfalse
場合、 if
ブロックは実行されません。安全なナビゲーション演算子は、 nil
値のみを認識しますが、 false
などの値を許可します。 address
がfalse
場合、SNOを使用するとエラーが発生します。
house&.address&.street_name
# => undefined method `address' for false:FalseClass