マジセミドライブ

ウェビナー関連のニュースやITサービス&ツールの最新情報を随時配信します。

OSS情報

2020.01.01

【OSS情報アーカイブ】Ruby

【OSS情報アーカイブ】Ruby

※当記事に記載されている情報は、古くなっている場合があります。オフィシャルサイトで最新情報をご確認ください。

コンテンツ

「Ruby」とは

概要

Ruby(ルビー)は、日本製オープンソースオブジェクト指向プログラミング言語です。

「Enjoy Programming!」が設計思想になっていて、主にWebアプリケーション開発に使われています。

「シンプル」「読みやすさ」「高機能」が人気となり世界に認められた日本製言語です。

経緯

Rubyは、日本人の「まつもとゆきひろ(通称Matz)」さんが開発されたプログラミング言語で、1993年に生まれて、1995年に発表されました。

「Ruby」という名前は、まともとさんの同僚が7月生まれだったため、その7月の誕生石(ルビー)が由来です。ちなみに、まつもとさんは4月生まれ(ダイヤモンド)とのことです。

2011年に、IPA(独立行政法人情報処理推進機構)が進めるプロジェクトにおいて、Rubyの技術規格書が、「JIS X 3017」として制定されました。

そして、2012年には、ISO/IEC(国際標準化機構/国際電気標準会議)の標準規格、「ISO/IEC 30170」として承認されました。

日本発のプログラミング言語が国際規格となるのはRubyが初めての偉業となっています。

世界的シェア拡大

Rubyは、Webアプリケーションフレームワーク「Ruby on Rails」に採用されブレイクしたこともあり、日本国内にとどまらず全世界に普及し、非常に多くの開発者に利用されています。

「fluentd」、「Redmine」、「Cloud Fundry」などもRubyで開発されています。

オフィシャルサイト情報

■オフィシャルサイト

→ruby-lang.org

■ライセンス情報

Rubyのライセンスは「Rubyライセンス」と「BSDライセンス」のデュアルライセンスです。

詳細について、こちらを参照ください。
→Ruby →license.txt

■動作環境

Rubyのプログラムは、移植性が高く、Ruby実行環境がインストールされていれば、Windows、Linux、MacOSなど、さまざまな環境で動作させることができます。

■ダウンロード

→Ruby →ダウンロード

同様製品

同様な機能を提供する製品として、次のようなものがあります。

オープンソース製品:「Perll」「PHP」「Python」など。

主な特徴

■設計思想「Enjoy Programming!」

開発者のまつもとさんは、「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミングを楽しむことである(Enjoy Programming)」と述べています。

Perlのような手軽さで「楽しく」オブジェクト指向しようという言語になっています。

シンプルで分かりやすい文法、洗練された例外処理機構などにより、初心者でも分かりやすいコードを書くことができます。

■オブジェクト指向

Rubyにおいて、数値型や文字型の値なども、すべてオブジェクトとなっており、純粋なオブジェクト指向言語といえます。

たとえば、「65」という数値もオブジェクトなので、文字コードを文字に変換する「chr」というメソッドを使えます。「65.chr」は’A’を返します。

■インタプリタ言語

Rubyは、主にインタプリタ言語として実装されています。

たとえば Javaの場合、ソースコードを書いた後にコンパイルという処理を行い、Java仮想マシンが理解できるバイトコードに変換する必要があります。

しかし、Rubyは、書いたソースコードをコンパイルせずに、そのまま実行させることができます。

■エキスパートプログラマーにも対応

Rubyは初心者でも簡単にコードを書けるような分かりやすくなじみやすい言語ですが、一方で、エキスパートプログラマーにとっては奥深い言語でもあります。

C#やJavaなどの言語は、制約が強力であるため、誰が書いても同じようなコードになります。しかし、Rubyは、プログラマーが希望すれば、制約を緩めることもできてしまいます。特に、「黒魔術」とまで言われるメタプログラミングは、最たるものです。

Rubyは、初心者にも、エキスパートにも、エキサイティングなコーディングを提供します。

■主な機能

・演算子オーバーロード
・例外処理機能
・イテレータとクロージャ
・ガーベージコレクタ
・ダイナミックローディング
・マルチスレッド
・Perlと同等のテキスト処理機能
・正規表現による検索機能
・メモリが許す限り巨大な桁の整数を扱うことができる
・OSのシステムコールを直接呼び出す機能

Rubyがよく分かる「お役立ちサイト」のご紹介

■Rubyプログラミングを始めるための基礎知識とインストール

Rubyについての解説があり、Ruby実行環境を「OS X」にインストールして「Hello World!」を表示するまでの解説をしています。

また、標準入力からRubyのコードを簡単に入力/実行できるツール「irb」についても紹介しています。

→Rubyプログラミングを始めるための基礎知識とインストール

■初心者におすすめ!Rubyを学習できる無料サービス7選

ブラウザ上でRubyについて無料で学習できるサイトを紹介しています。Ruby入門レッスン、コードを入力する演習などを行えます。

→初心者におすすめ!Rubyを学習できる無料サービス7選

「Ruby」参考情報 第1回 Rubyの正規表現による文字列置換と変数の利用

(1)Rubyの正規表現

Rubyはテキスト処理も得意な言語です。強力な正規表現を使用できます。

■Rubyでの正規表現の表現方法

Rubyでは、「/」と「/」で囲まれた文字列が正規表現として扱われます。
/&#165d{3,}/
これは、3桁以上の数字を表します(123 や 4567 など)。

■メタ文字リファレンス

「&#165d」のような正規表現を表す文字列のことを、「メタ文字」といいます。こちらのサイトでは、主要なメタ文字と、正規表現を使った基本的な処理の仕方を解説しています。

→むかぁ~どっとこむ Ruby入門5、正規表現まとめ~これからにRubyに乗り換えする人へ~

(2)正規表現による文字列置換

基本的な文字列置換方法として、「gsub」や「sub」メソッドがあります。

■gsubによる置換例

#『「a」で始まり、「a」が1回以上続き、最後が「a」以外の任意の一文字』となっている文字列を「ZZZ」に置換します。
aaa1 bbb2 aaa3.gsub(/a+./, ‘ZZZ’)
 ↓
#「aaa1」と「aaa3」が「ZZZ」に置換されます。
ZZZ bbb2 ZZZ

■gsub と sub の違い

aaa1 bbb2 aaa3.sub(/a+./, ‘ZZZ’)

#「aaa1」は「ZZZ」に置換されますが、「aaa3」はそのままです。
ZZZ bbb2 aaa3

subは、最初の1回だけ置換処理を行います。

gsubは、該当箇所すべてに対して置換処理を行います。

■参考サイト

こちらのサイトでは、Rubyの文字列置換方法について、横断的に解説しています。一通り見ておくと、全体的なイメージを掴めます。「Regexpクラス」というのは正規表現を扱うクラスです。

→若手エンジニア/初心者のためのRuby 2.1入門(5):RubyのString/Regexpクラスによる強力な文字列操作/正規表現

(3)文字列置換と変数の利用

■対象文字列を変数として置換文字として使用する

xAA1yy xxAAAyy xxAA3yy’という文字列を
zzAA1zzのような形に変換したいとします。’xx’と’yy’を、’zz’に置換します。
xxAA1yy xxAAAyy xxAA3yy.gsub(/..(AA&#165d)../){‘zz’ + $1 + ‘zz’}

zzAA1zz zzAA3zz
検索対象は、「/..(AA&#165d)../」なので、「任意の2文字+’AA’+数字1文字+任意の2文字」となります。「xxAA1yy」「xxAA3yy」が対象文字列となり、「xxAAAyy」は除外されます。
「/..(AA&#165d)../」において、「AA&#165d」を括弧で囲んでいます。括弧を使用すると、置換後の文字列とすることができます。
置換後文字列は、「{‘zz’ + $1 + ‘zz’}」の部分です。変数「$1」の部分に、「AA1」と「AA3」が入ることになります。

■記述構文に注意

他にも記述法があるのですが、構文を間違えてしまうと正常に機能しません。こちらのサイトに解説があります。

→勉強日記 subやgsubで括弧とマッチした部分の再利用、および式展開の方法

「Ruby」参考情報 第2回 Rubyの演算子の使い方まとめ

(1)Ruby演算子の使い方

■演算子とは

プログラミングにおいては、主に記号を使用して演算を指示するものを演算子といいます。数式の四則演算記号に似ています。足し算の「1+2」の「+」が演算子に該当します。

ただ、各プログラミング言語ごとに、特別な記号や使い方が存在します。

Rubyの基本的な演算子について、紹介します。

■代数演算子

数学の式と同じような演算子です。

・加算「+」 1+2
・減算「-」 5-3
・乗算「*」 2*3
・除算「/」 10/3(10を3で割った答え→3)
・剰余「%」 10%3(10を3で割った余り→1)
・べき乗「**」 5**2(5の2乗→25)

■代入演算子

変数に値をセットする場合に使用します。
num=10 (変数numに10を代入)

複数の変数に同時に値をセットすることもできます。
x, y, z = 1, 2, 3

代数演算子の省略形の形(自己代入)としても使えます。
num += 2 (num = num + 2 と同じ)
num -= 2 (num = num – 2 と同じ)
num *= 2 (num = num * 2 と同じ)
num /= 2 (num = num / 2 と同じ)

■比較演算子(関係演算子)

2つの値について比較を行います。if文などの条件判定に使用されます。

・a > b (aはbより大きい)
・a >= b (aはb以上)
・a < b (aはbより小さい)
・a <= b (aはb以下)
・a == b (aはbと等しい)

■論理演算子

複数の比較条件を組み合わせる場合に、「かつ」や「または」などで接続するための演算子です。
(a&gt0) &amp&amp (b&gt0)
(aは0より大きい かつ bは0より大きい)
※両方の条件がtrueの場合のみ、trueとなります。
(a&gt0) || (b&gt0)
(aは0より大きい または bは0より大きい)
※どちらかの条件がtrueならば、trueとなります。

■三項演算子

条件式の結果によって、異なる値を返す演算子です。
構文「(条件) ? 式1 : 式2」
(a&gtb) ? ‘aが大きい’ : ‘bが大きい’
※(a&gtb)がtrueならば、 ‘aが大きい’ が返されます。
※(a&gtb)がfalseならば、 ‘bが大きい’ が返されます。

(2)Ruby演算子についての「お役立ちサイト」のご紹介

■参考サイト①

Rubyで使える演算子が、一覧として紹介されています。リファレンスとして参照できます。

→Ruby入門 – 演算子

■参考サイト②

こちらのサイトでは、Rubyの条件分岐や比較演算子などについて、ブラウザ上で演習問題などをやりながら学習できるサイトです。

開発環境をインストールしなくても、ブラウザのみで、無料で試せますので、ぜひ、チャレンジしてみてください。

→paiza開発日誌 条件分岐、比較演算子が最速でわかる!Rubyの無料学習サービスやってみた

「Ruby」参考情報 第3回 Rubyの配列まとめ(初期化の方法、要素数の取得、ループ処理)

(1)Rubyの配列

Rubyの配列は、基本的に他のプログラミング言語と同じような機能を持っています。

■配列の定義

array_animals = [‘犬’, ‘猫’, ‘カピバラ’]

■配列の参照

インデックスは0から開始

array_animals[0] → ’犬’
array_animals[2] → ’カピバラ’

マイナスインデックスを使用可能

array_animals[-1] → ’カピバラ’ ※最後の要素
array_animals[-2] → ’猫’ ※最後から2番目の要素

(2)配列初期化の方法

■空の配列作成

どちらの方法でも、同じように空の配列が作成されます。

array_test1 = []
array_test2 = Array.new

■配列要素の追加方法

どちらの方法でも、同じように要素を追加できます。
array_test1.push(1)
array_test1 &lt&lt 2
array_test1 &lt&lt 3
array_test1の中身は、[1, 2, 3]となります。

(3)要素数の取得

要素数を取得するために、「Array#length」、または、「Array#size」を使います。

どちらも、3が返されます。

array_test1.length
array_test1.size

(4)ループ処理

■for文

for文を使用すると、配列に格納されている各要素を順番に取り出して繰り返し処理を実行できます。

構文

for 変数 in 配列オブジェクト do
  処理1
  処理2
end

サンプルコード

array_animals = Array[‘犬’, ‘猿’, ‘キジ’]
for var in array_animals do
  print(‘お供 = ‘ + var + ‘¥n’)
end

実行結果

お供 = 犬
お供 = 猿
お供 = キジ

■eachメソッド

eachメソッドでも、同様な処理を行えます。

構文

配列オブジェクト.each{|変数|
  処理1
  処理2
}

サンプルコード

array_animals = Array[‘犬’, ‘猿’, ‘キジ’]
array_animals.each{|var|
  print(‘お供 = ‘ + var + ‘¥n’)
}

実行結果

お供 = 犬
お供 = 猿
お供 = キジ

(5)Rubyの配列に関する「お役立ちサイト」

■参考サイト①

Rubyの配列の使い方について、基本の部分から順番に解説しています。

→若手エンジニア/初心者のためのRuby 2.1入門(3): Rubyの配列、ハッシュテーブルを表現するArray、Hashクラスの使い方

■参考サイト②

「配列オブジェクト」、「要素とインデックス」、「要素へのオブジェクトの代入」など、カテゴリごとに分かれていて、逆引きリファレンスとして参考にできます。

→RubyLife 配列

「Ruby」参考情報 第4回 Rubyの文字列処理まとめ(比較、結合、分割、検索)

(1)Rubyの文字列比較

■「==」

同一文字列の判定には、「==」を使用します。

サンプルコード

if ‘dog’ == ‘dog’
  print(‘同じです’)
else
  print(‘違います’)
end

結果

同じです

■「!=」

同一文字列ではないという判定は「!=」を使用します。

サンプルコード

if ‘dog’ != ‘cat’
  print(‘違います’)
else
  print(‘同じです’)
end

結果

違います

(2)Rubyの文字列結合(文字列連結)

文字列結合には、いろいろな手段があります。以下のサンプルは、すべて同じ結果になります。

■サンプルコード

s = ‘abc’ + ‘123’
s = ‘abc’ << '123'
s = ‘abc’.concat(‘123’)

■結果

「s」には「abc123」がセットされます。

※「+」よりも「<<」のほうが高速に処理できます。

(3)Rubyの文字列分割

■「split」メソッド使用例(1)

文字列分割の主な手段として「split」メソッドがあります。区切り文字を指定すると、指定文字列で区切った文字列配列を返します。正規表現での文字列分割も可能です。

サンプルコード

a = ‘dog,cat,bird’
b = a.split(‘,’)

結果

「b」には、[‘dog’, ‘cat’, ‘bird’]の文字列配列がセットされます。

■「split」メソッド使用例(2)

区切り文字として、'(空文字列)を指定すると、1文字ごとに分割されます。

サンプルコード

a = ‘abcde’
b = a.split(‘)

結果

「b」には、[‘a’, ‘b’, ‘c’,’d’,’e’]の文字列配列がセットされます。

(4)Rubyの文字列検索

■「index」メソッド

「index」メソッドは、検索対象文字(列)が何文字目に存在するのかを返します。

サンプルコード

s = ‘abcde’
pos = s.index(‘cd’)

結果

posには、「2」がセットされます。

a開始位置は0、’b’開始位置は1、’c’開始位置が2 となります。

■「rindex」メソッド

「index」メソッドは左から検索しましたが、「rindex」メソッドは右から検索していきます。

サンプルコード

s = ‘abcdexcde’
pos = s.rindex(‘cd’)

結果

posには、「6」がセットされます。

左側の’cd’ではなく、右側の’cd’の位置が返されます。

■「include」メソッド

「include」メソッドは、検索対象文字(列)が存在しているかどうかをtrue/falseで返します。

サンプルコード

s = ‘abcde’
check = s.include?(‘bc’)

結果

checkには、「true」がセットされます。

「Ruby」参考情報 第5回 Rubyのファイルへの読み込みと書き込み

(1)Rubyのファイル読み込み

■読み込み用サンプルファイル

読み込み用サンプルファイル(sample.txt)には、以下の内容が記述されているものとします。

1:犬
2:猿
3:キジ

■1行ずつ読み込む 「each_line」と「foreach」

サンプルコード1

「File.open」でファイルをオープンして、変数「file」にファイルオブジェクトをセットします。

ファイルオブジェクト「file」の「each_line」メソッドで1行ずつ読み込み、変数「file_line_animal」にセットして、出力します。

File.open(‘sample.txt’) do |file|
  file.each_line do |file_line_animal|
    puts file_line_animal
  end
end

サンプルコード2

サンプルコード1の処理を「File.foreach」メソッドでまとめて簡略化できます。

File.foreach(‘sample.txt’) do |file_line_animal|
  puts file_line_animal
end

結果

どちらのコードでも、同じ結果が出力されます。

1:犬
2:猿
3:キジ

■1度で全体を読み込む 「read」

サンプルコード

最初に「read」メソッドで全体を読み込み、「split(‘¥n’)」で改行区切り単位で処理することで、1行ごと処理します。

File.open(‘sample.txt’) do |file|
  file.read.split(‘¥n’).each do |file_line_animal|
    puts file_line_animal
  end
end

結果

1:犬
2:猿
3:キジ

(2)Rubyのファイル書き込み

■書き込み用サンプルファイル

書き込み用サンプルファイル(sample.txt)は、以下の内容が記述されているとします。

1:犬
2:猿
3:キジ

■1行ずつ書き込む 「puts」 ※上書きモード(w)

「File.open」でファイルをオープンします。この時に第2引数として「w」を付けます。これは、書き込みモードを指定することになります。

「puts」メソッドで書き込みます。

サンプルコード

File.open(‘sample.txt’,’w’) do |file|
  file.puts ‘A1:ももたろう’
end

結果

A1:ももたろう

上書きモード(w)について

sample.txtに記述されていた「犬」「猿」「キジ」が消えてしまい、「ももたろう」だけになります。

これは、ファイルオープン時に指定した「w」は上書きモード指定であるため、ファイルを空にしてから書き込み処理を行います。

■1行ずつ書き込む 「print」「puts」 ※追記モード(a)

今度は、追記モード(a)でファイルをオープンして、書き込みます。

サンプルコード

File.open(‘sample.txt’,’a’) do |file|
  file.print ‘A2:きんたろう’
  file.puts ‘A3:うらしまたろう’
end

結果

A2:きんたろう
A3:うらしまたろう

追記モード(a)について

※追記モード(a)の場合は、対象ファイルの末尾から追記を行います。

※「print」は改行なし、「puts」は改行あり、で書き込みます。

「Ruby」参考情報 第6回 Rubyの標準入力と標準出力

(1)標準入力

■標準入力「STDIN」

使用例

標準入力「STDIN」からデータを受け取るには「gets」を使用します。

gets」は標準入力から行単位で読み込みます。行末の改行文字を取り除きません。

サンプルコード

#標準入力取得ループ
while str = STDIN.gets
  #改行コードを除去した文字列が’exit’の場合ループ終了
  break if str.chomp == ‘exit’
  #取得した標準入力文字列を出力
  #「{str}」で変数の内容を出力します
  puts ‘input text:{str}’
end

結果

dog #キーボード入力
input text:dog
cat #キーボード入力
input text:cat
exit #キーボード入力

■コマンドライン引数

変数「ARGV」にはコマンドラインで指定された引数が配列としてセットされています。

サンプルコード(argb_test.rb)

#コマンドライン引数1番目を出力
puts ARGV[0]
#コマンドライン引数2番目を出力
puts ARGV[1]
#コマンドライン引数3番目を出力
puts ARGV[2]

結果

argb_test.rb dog cat rabbit #キーボード入力
dog
cat
rabbit

(2)標準出力

■標準出力「STDOUT」と標準エラー「STDERR」

2種類に分けて出力させることができます。チェック用、デバッグ用などの用途に分けて出力できます。

サンプルコード(test.rb)

#標準出力
STDOUT.puts ‘標準出力STDOUT’
#標準エラー
STDERR.puts ‘標準エラーSTDERR’

(結果1)リダイレクトなしの場合

どちらも出力されます。

test.rb #キーボード入力
標準出力STDOUT
標準エラーSTDERR

(結果2)標準出力をリダイレクト

「test.rb 1>out.log」と実行すると、標準出力をログファイルに書き出すことができます。

「1」は標準出力を表します。省略も可能です。

test.rb 1>out.log #キーボード入力
標準エラーSTDERR ←標準エラーはコンソールへ

※out.logの中に、「標準出力STDOUT」が出力されます。

(結果3)標準エラーをリダイレクト

「test.rb 2>err.log」と実行すると、エラー出力をログファイルに書き出すことができます。「2」はエラー出力を表します。

省略は不可です。

test.rb 2>err.log #キーボード入力
標準出力STDOUT ←標準出力はコンソールへ

※err.logの中に、「標準エラーSTDERR」が出力されます。

■「print」と「puts」と「p」

3つとも出力を行いますが、微妙に異なります。

サンプルコード

#print
print(‘Hello Ruby World ‘)
print(12345)
#puts
puts(‘Hello Ruby World ‘)
puts(12345)
#p
p(‘Hello Ruby World ‘)
p(12345)

結果(print)

Hello Ruby World 12345
※「print」は改行されません

結果(puts)

Hello Ruby World
12345

※「puts」は改行されます

結果(p)

Hello Ruby World
12345

※「p」は、文字列が「’」で囲まれます。主にデバッグ用に使われます。

「Ruby」参考情報 第7回 Rubyの変数(ローカル変数、インスタンス変数、クラス変数、グローバル変数)

(1)ローカル変数

■命名規則

「英小文字」または「_」で始めます。

■スコープ

(宣言した位置から)その変数が宣言されたブロック、メソッド定義、クラス/モジュール定義の終わりまでとなります。

■サンプルコード

class Test
  #ローカル変数定義(1)
  my_hobby_1 = ‘ゲーム’
  #メソッド定義
  def out_my_hobby
    #my_hobby_1を出力
    #スコープ範囲外のローカル変数参照→エラーとなる
    puts my_hobby_1
    #ローカル変数定義(2)
    my_hobby_2 = ‘読書’
    #my_hobby_2を出力→出力される
    puts my_hobby_2
  end
end
#クラスインスタンス生成
test = Test.new
#out_my_hobbyメソッドを実行
test.out_my_hobby

(2)インスタンス変数

■命名規則

「@」で始めます。

■スコープ

インスタンス内の全メソッドで共通して使用できます。インスタンスごとに固有になります。

■サンプルコード

class Test
  #メソッド インスタンス変数に値をセット
  def set_my_hobby(name)
    #インスタンス変数定義
    @my_hobby = name
  end
  #メソッド インスタンス変数を出力
  def out_my_hobby
    puts @my_hobby
  end
end
#クラスインスタンス生成(1)
test_1 = Test.new
#(1)set_my_hobbyメソッドを実行
test_1.set_my_hobby(‘ゲーム’)
#クラスインスタンス生成(2)
test_2 = Test.new
#(2)set_my_hobbyメソッドを実行
test_2.set_my_hobby(‘読書’)
#(1)out_my_hobbyメソッドを実行→「ゲーム」
test_1.out_my_hobby
#(2)out_my_hobbyメソッドを実行→「読書」
test_2.out_my_hobby

(3)クラス変数

■命名規則

「@@」で始めます。

■スコープ

クラス、および、そのクラスから生成されるインスタンスで共有されます。

■サンプルコード

class Test
  #メソッド クラス変数に値をセット
  def set_my_hobby(name)
    #クラス変数定義
    @@my_hobby = name
  end
  #メソッド クラス変数を出力
    def out_my_hobby
    puts @@my_hobby
  end
end
#クラスインスタンス生成(1)
test_1 = Test.new
#(1)set_my_hobbyメソッドを実行
test_1.set_my_hobby(‘ゲーム’)
#(1)out_my_hobbyメソッドを実行
#(1)’ゲーム’が出力される
test_1.out_my_hobby
#クラスインスタンス生成(2)
test_2 = Test.new
#(2)set_my_hobbyメソッドを実行 クラス変数が’ゲーム’から’読書’に書き換えられる
test_2.set_my_hobby(‘読書’)
#(2)out_my_hobbyメソッドを実行
#(2)’読書’が出力される
test_2.out_my_hobby
#(1)test_1インスタンスでも’読書’が出力される
test_1.out_my_hobby

(4)グローバル変数

■命名規則

「$」で始めます。

■スコープ

グローバル変数は、その「グローバル」の名の通りに、オブジェクトの壁も乗り越えて、プログラムのどこからでも共有されます。

■サンプルコード

class Test
  #グローバル変数定義
  $my_hobby = ‘ゲーム’
  #メソッド グローバル変数を出力
  def out_my_hobby
    puts $my_hobby
  end
end
#クラスインスタンス生成
test = Test.new
#out_my_hobbyメソッドを実行
test.out_my_hobby

「Ruby」参考情報 第8回 Rubyにインクリメント演算子が無い理由

(1)インクリメント演算子とは

■インクリメント演算子

数値型変数の値を1だけ増加させる演算子です。

「++」記号を使用します。

「num++;」は、「num = num+1;」「num += 1;」と同じになります。

■デクリメント演算子

数値型変数の値を1だけ減少させる演算子です。

「–」記号を使用します。

「num–;」は、「num = num-1;」「num -= 1;」と同じになります。

■(Java)サンプルコード

int num = 3&#059
System.out.println(num)&#059 //出力1
num++&#059 //プラス1
System.out.println(num)&#059 //出力2
num++&#059 //プラス1
System.out.println(num)&#059 //出力3
num–&#059 //マイナス1
System.out.println(num)&#059 //出力4

■(Java)サンプルコード 結果

3 //出力1
4 //出力2
5 //出力3
4 //出力4

(2)Rubyにインクリメント演算子が無い理由

多くのプログラミング言語(Java、Perl、PHP、C系言語など)では、インクリメント演算子を使うことができます。

しかし、Rubyでは、インクリメント演算子は使えません。ちなみに、Pythonも使えません。

「Rubyにインクリメント演算子が無い理由」について、「Ruby開発者(まつもとさん)のお答え」と「Rubyユーザの皆さんの見解」を引用して紹介します。

■Ruby開発者(まつもとゆきひろさん、Matzさん)のお答え

質問

3) 記号的な記法 これは単なる私の趣味ですが, 単項インクリメントとかがたまに欲しくなります. i += 1 でいいわけですが. i++ と書いて怒られる (^^;

回答

すんません.この件は以前から指摘されているのですが(演算子はCに似ているのに++と–は対応する演算子が無い),++の動作が本質的に「変数を操作する」ものであるため,変数がオブジェクトでないRubyでは導入できないでいます.++や–の「オブジェクト指向的意味」がRubyの他の部分と整合性を保ったまま定義できれば採用したいのですが….

→Re: Questions on specs and threads

■Rubyユーザの見解(1)

Rubyではその他の多くのプログラミング言語と違い、「変数」を「オブジェクト」として扱っていないようです。そのためRubyにおいての変数は、数そのものへのポインタということになり、ここに破壊的動作である++演算子を使用してしまうと、「ポインタの位置がインクリメントされる」という正しく破壊的な結果がもたらされてしまうようです。

その結果どういうことになるかというと、変数の値だけでなく、プログラム内で扱っている1という数字へのポインタが2を向くようになってしまいます。つまり、そのプログラム内では「1も2も2」に変更されてしまうのです。

そのため、Ruby開発者のまつもと氏は「本当は使えるようにしたいけど、Rubyの設計上禁止せざるを得ない」というようなことを言っています。

→アベログ →Rubyでは++演算子によるインクリメントができない

■Rubyユーザの見解(2)

n++ はオブジェクト n に対するメソッドのように見えます。 しかし、メソッドは変数 n ではなく、n が参照しているオブジェクトに対する操作です。 それに従った、数値(例: 2)オブジェクトの意味を変える(例: 2 オブジェクトを 3 の意味にする)という処理をするわけではありません。 インクリメントは、変数が参照する数値オブジェクトを、別の数値オブジェクトに切り替える処理になります。

つまり、見た目から推測される動作が異なる(メソッドに見えるがそうではない)というわけです。 メソッドに見えてしまう理由は、おそらく = が表記されていないからでしょう。 このような考えはオブジェクト指向に特殊な考えと考えることもできるでしょうが、そこから外れるということは統一性を欠いて複雑になるということです。 オブジェクト指向の考えなしに現在の高機能なプログラミング言語はできません。

→Snap Note 開発記 from ソフトウェアデザイン館 Sage Plaisir 21 →インクリメントの演算子を書くな – リーダブル・コード(35)

■Rubyユーザの見解(3)

・Rubyのメソッドの引数は値渡し
・Rubyの変数は全てオブジェクトを指し示すポインタに似た何か
・Rubyの変数はラベル

Cにおける変数は箱だと例えられるが、Rubyにおける変数はラベルと例えられることがある。Cの変数では、メモリ上の箱に値がそのまま入っている。代入をすれば、箱が複製される。

一方、Rubyではメモリ上の箱のどこかに値が入っており、変数はラベル(箱への参照)を持っているだけにすぎない。 変数を代入すると、メモリ上のデータはそのままに、ラベルだけがコピーされるのである。

Rubyにインクリメント演算子がない理由は簡単で、RubyのFixnumクラスやBignumクラスは immutableだからだ。つまり、オブジェクト自体を破壊的に変更することはできない。

もし、オブジェクト自体を破壊的に変更できたらどうなるだろうか。大変なことになってしまう。

→gam0022.net →初心者が混乱しやすいRubyの変数

Rubyでインクリメント演算子が使えない理由まとめ

以上の内容を、ごくごく簡単にまとめてみると、次のようにまとめることができるでしょうか。

・Rubyの変数は、オブジェクトに対するポインタ(ラベル)のようなもの

・ポインタに対してのインクリメント処理を可能にしてしまうと、ポインタの位置がインクリメントされてしまう

この記事のタグ一覧

おすすめの記事

【デジタル寺田の3分用語解説】「 VMWare 問題 」とは?🖥️

デジタル寺田の3分用語解説

2024.11.18

【デジタル寺田の3分用語解説】「 VMWare 問題 」とは?🖥️

「 VMWare 」の仮想化技術は、「ITインフラの効率化」に大きく貢献する技術ですが、Broadcomによる買収後のライセンス変更が大きな問題として注目されています。柔軟で慎重な契約見直しが今後の鍵となります。

【デジタル寺田の3分用語解説】「 2029年問題 」とは?📅

デジタル寺田の3分用語解説

2024.11.18

【デジタル寺田の3分用語解説】「 2029年問題 」とは?📅

「 2029年問題 」とは、高校でのデジタル教育改革により、新入社員と既存社員間でデジタルスキル格差が拡大する懸念を指します。企業は早急に対応が求められています。この格差は、企業競争力や業務効率にも、影響を及ぼす可能性があります。

【デジタル寺田の3分用語解説】「 経済産業省:コンテンツ制作のための 生成AI 利活用ガイドブック 」とは?📘

デジタル寺田の3分用語解説

2024.11.18

【デジタル寺田の3分用語解説】「 経済産業省:コンテンツ制作のための 生成AI 利活用ガイドブック 」とは?📘

経済産業省による「 生成AI 利活用ガイドブック 」は、企業やクリエイター向けに、安心して「生成AI」を利用するための、「指針」「実例」「注意点」を明示しています。「業務効率化」や「新しいアイデア創出」の支援を目的としています。