Rubyの演算子10種類|演算子の優先順位や再定義についても解説

Rubyの演算子10種類|演算子の優先順位や再定義についても解説のアイキャッチイメージ

Rubyでは演算子を再定義できる?


Rubyは柔軟な言語として知られています。Rubyの演算子は、同時にメソッドの糖衣構文(シンタックスシュガー)でもあるため、演算子を再定義(オーバーライド)することができるのです。

ただし、中には再定義できない演算子もあります。制御構文を構成する演算子は、演算子(メソッド)の組合せであるため、自己代入演算子(順次、条件分岐、繰り返しといった制御構造をとる)は再定義できません。

再定義が可能なのはメソッド呼び出しのもの

Rubyの再定義が可能な演算子は、メソッドとして呼び出されたものになります。

すなわち、単項演算子、代数演算子、比較演算子、ビット演算子、文字列演算子、正規表現演算子、not演算子、ハッシュ演算子(配列リテラル・配列参照など)、コマンド出力リテラルなど、合わせて28種類が再定義の可能な演算子記法になります。

Rubyの演算子10種類


Rubyは、プログラミングの利便性を高める目的で、一部の制御構造とメソッド呼び出しは演算子を使用します。

よく利用される演算子は様々なメソッドで重複して登場しますが、メソッドの機能性によってグループ分けをして整理すると把握しやすいでしょう。Rubyでは様々な演算子がどのように活用されているのか、10種類に分けてご紹介します。

1:代入演算子

代入演算子は、変数などへの値の代入や、定数およびローカル変数の宣言として利用されます。Rubyの代入式の左辺は、「変数」「配列参照」「属性参照」のいずれかでなければなりません。

基本的な代入演算子「=」で、左辺に右辺を代入することができます。また、代入演算子には、「=」と他の演算子を組み合わせた自己代入演算子もあります。加えて、代入には、複数の式または配列から同時に代入を行う多重代入があります。

ちなみに、代入演算子および自己代入演算子は、再定義することはできません。

Rubyにインクリメント・ディクリメントはない

Rubyには、他の言語でよく使われるような「i++」や「i–」のような、インクリメント(加算子)、ディクリメント(減算子)といった演算子は用意されていません。代わりに、他の演算子を代入演算子「=」と組み合わせた、「+=」「-=」といった自己代入演算子を用います。

2:代数演算子

代数演算子は、四則演算(足し算、引き算、掛け算、割り算)と剰余(割り算の余り)およびべき乗の演算をする、代数計算を行うメソッドになります。

足し算、引き算、掛け算、割り算、剰余を行う代数演算子は、それぞれ「+」「-」「*」「/」「%」とオーソドックスな記述になりますが、べき乗は「**」となる点がRubyの特徴と言えます。

6+3 6と3の足し算(9)
6-3 6と3の引き算(3)
6*3 6と3の掛け算(18)
6/3 6と3の割り算(2)
5%3 5と3の余り(2)

3:比較演算子

比較演算子とは、左辺と右辺を比べるメソッドです。「大なり」「小なり」「等しい」「等しくない」などを「true」か「false」で返します。「==」「!=」「>」「>=」「<」「<=」そして「<=>」「===」があります。

a == b aとbが等しい
a != b aとbが等しくない
a < b aよりbが大きい
a > b aよりbが小さい
a <= b aよりbが大きいか等しい
a >= b aよりbが小さいか等しい

また比較演算子「<=>」は、a < b であれば「-1」、a == b であれば「0」、a > b であれば「1」、比較できない時は「nil」を返します。

特殊な等号演算子「===」は、case文での比較に用いられ、デフォルトは「Object#==」とほぼ同じ動きをします。この演算子の挙動は、サブクラスの所属クラスに合わせて適宜再定義されます。

よって他言語で定義されている厳密等価演算子とは対照的に、Rubyでは緩い等価性比較がなされます。

4:論理演算子

論理演算子は、論理積(and)や論理和(or)を「true」か「false」で返します。

Rubyの論理演算子のほとんどは再定義不可能な(制御構造を構成する)演算子の記法ですが、Rubyにおける記号「!」は再定義可能な演算子として扱われています。

!a aを満たさない(not演算子)
not a aを満たさない
a and b aとbの両方を満たす
a or b aかbのどちらかを満たす
a && b aとbの両方を満たす(and)
a || b aかbのどちらかを満たす(or)

5:ビット演算子

C++などで活用されるように、Rubyでもビット演算を行うことができます。

ビット演算やシフト演算はIntegerクラスのオブジェクトを扱います。ビット演算とは、ある数値を0と1の2進法で演算することを指します。コンピュータは2進法で計算しているため、ビット演算を利用することで処理速度を上げることが期待できます。

~a aのビット否定(ビットが1の場合は0、0の場合は1と反転する)
a & b aとbのビット積(aかつbでもビットが1なら1にする)
a | b aとbのビット和(aまたはbでビットが1なら1にする)
a ^ b 排他的論理和(aとbで異なるビットを1にし、一致すれば0にする)
a < < n aを左へnビット桁移動(シフト)する
a > > n aを右へnビット桁移動(シフト)する
a[n] aのnビット目(最下位ビットが0番目)が立っていれば(1ならば)1にする

6:文字列演算子

Rubyには、Perlを手本とした強力な正規表現検索や文字列操作の機能を備えています。文字列はダブルクォートまたはシングルクォートで囲みます。

文字列はStringクラスに属し、Stringの各種メソッドにより文字列同士の比較・結合が行えます。厳密にはRubyで直接に文字列演算子と呼ぶものはありませんが、ここではStringメソッドとして文字列操作に利用できる演算子の一部をご紹介しましょう。

“str” + “ing” 「str」と「ing」を連結する(新たに「string」が生成される)
“str” << “ing” 「str」と「ing」を破壊的に連結する(「str」は「string」に変わり「str」はなくなる)

Rubyではこれ以外にも、「%」「*」「@」「=」「~」「[]」といった演算子が使われる記法が組み合わされたメソッドが存在します。

+と<<の違い

RubyのString#+メソッドは非破壊的な連結をしますが、String#<<メソッドは破壊的な連結をします。

たとえば、以下の例では文字列aは「str」のままです。

a = “str”
a + “ing”

しかし以下の例では、文字列aは最初に定義した「str」ではなく、「string」になります。

a = “str”
a << “ing”

7:3項演算子

3項演算子は条件演算子とも呼ばれます。「xx ? yy : zz」の形で記述し、「if xx then yy else zz end」と同じです。xxの結果によってyyまたはzzを返します。

つまり、制御構造のひとつであるif構造を、「?」と「:(コロン)」の演算子だけで簡略化して記述できる記法になります。

8:正規表現演算子

正規表現を扱う演算子には「~(チルダ)」が用いられます。正規表現と文字列を比較し、マッチするか否かで「true」か「false」が返されます。両辺を入れ替えても機能します。

「=~」は両辺がマッチした場合に「true」を返し、「!~」は相違があった場合に「true」を返します。

9:ハッシュ演算子

ハッシュは、ハッシュテーブル(連想配列)を扱うHashクラスのインスタンスです。キーとなる任意の種類のオブジェクトから、値(バリュー)となる任意の種類のオブジェクトへの、関連づけを行うことができます。

ハッシュを生成するハッシュ式に利用される演算子は基本的に、「{}」「:(コロン)」「=>」「,(カンマ)」です。「{ :a => “A”, :b => “B”, :c => “C” }」や「{ a:”A”, b:”B”, c:”C” }」のように記述できます。

この例の場合、aがキーでAがバリューになります。このようハッシュの記法によって、ハッシュテーブルにデータを取り出しやすい形で格納しておくことができます。

10:配列演算子

配列はArrayクラスのインスタンスです。データを一次元的に格納します。

配列を生成する配列式に利用される演算子は、基本的に「[]」と「,(カンマ)」です。たとえば「[1, 2, 3]」のように記述します。このような記法のほかに、要素が文字列リテラルかシンボルリテラルの場合に限り、%記法 による配列表現も指定できます。

また、配列同士で、代数演算子のような演算子の使い方をしたり、一部の比較演算子・論理演算子を配列の演算でも使うことができます。

Rubyの演算子の優先順位は?


演算子には結合の優先順位が存在します。中にはRubyならではの優先順位が設定されており、それを利用して簡潔な文を書くことが可能です。

優先度が高いのは「::」クラスやモジュールのネストに使われる演算子です。

優先順位の高い順に列挙していくと、「[]」配列、単項演算子「+@」「!」not演算子「~」ビット否定演算子、「**」べき乗、単項演算子「-@」、「*」乗算「/」除算「%」合同式、「+」加算「-」減算です。

それに続き、「<<」「>>」シフト演算子、「&」論理積、「|」論理和「^」排他的論理和、比較演算子「>」「>=」「<」「<=」、比較演算子「<=>」「!=」「==」「===」等号演算子「=~」「!~」正規表現メソッド、「&&」論理積、「||」論理和、となります。

さらに優先順位が下がると、「..」「…」Rangeオブジェクトを作る範囲演算子、「?:」条件演算子、「=」代入演算子「+=」「-=」といった自己代入演算子、そして「not」演算子です。最も優先度が低いのは論理積「and」と論理和「or」になります。

処理の例

たとえば「2 + 3 * 4」という式は「2 + (3 * 4)」と解釈されます。これは演算子に結合の優先順位があり、「+」よりも「*」の方が順位が上だからです。

またたとえば、「&&(論理積)」は「||(論理和)」より優先順位が高いので、「a && b || c」は「(a && b) || c」として論理積が優先され、「a || b && c」も「a || (b && c)」として論理積が優先されます。

Rubyで使える演算子を知って効率的なコードを書こう


Rubyで使われる演算子を網羅的にご紹介しました。一部の記法を除けば、Rubyは、C言語やC++と非常に似通った演算子の使い方をしています。

Rubyの演算子はほとんどがシンタックスシュガーのため、見た目以上に多くの仕事をしてくれます。Rubyは他言語と比べ、記法が非常にシンプルなので、コードを短く早く書け、メンテナンスがしやすいという利点があります。

ぜひRubyの演算子の特徴をマスターして、効率的なコードを書けるようになりましょう。

インフラエンジニア専門の転職サイト「FEnetインフラ」

FEnetインフラはサービス開始から10年以上『エンジニアの生涯価値の向上』をミッションに掲げ、多くのエンジニアの就業を支援してきました。

転職をお考えの方は気軽にご登録・ご相談ください。