プログラミング > Ruby

Rubyに関するメモ



変数

  • 変数は小文字英字かアンダースコアで名前が開始するもの
  • 定数は大文字英字で名前が開始するもの
  • @で始まる変数名はインスタンス変数
  • @@で始まる変数名はクラス変数
  • $で始まる変数名はグローバル変数
a = 10  # これは変数
 
A = 10  # これは定数
 
 

変数のスコープ

ブロック内で定義された変数の寿命はブロック末端まで

擬似変数

self nil true false が擬似変数と呼ばれるもの
selfは他の言語でいうthis相当だと思われる(メソッドの実行主体を指すらしい)
擬似変数は他にも __FILE__ __LINE__ __ENCODING__ があるが、デバッグ用途かな?

配列

a = [1, 2, 3]   # 配列の生成
 
b = Array.new(5, 2) # [2, 2, 2, 2, 2] の生成 ※初期値をオブジェクトにすると参照のコピーで注意が必要
 
c = Array.new(5) { |i| i * i } # [0, 1, 4, 9, 16] の生成
 
print c[3]    # 配列へのアクセス
 
d = Array.new(3) {|i| Array.new(3,i) } # [[0, 0, 0], [1, 1, 1], [2, 2, 2]] の生成
 
print d[1][2]   # 2次元配列へのアクセス
 
e = []
 
e.push 1      # e = [1]
e.push 2, 3   # e = [1, 2, 3]
e.push [4, 5] # e = [1, 2, 3, [4, 5]]
 
f = [1, 2, 3, 4, 5, 6]
x = f.pop     # x = 6
y, z = f.pop(2)  # y = 4, z = 5
 
#配列の長さ
g = [1, 4, 9, 16, 25]
s1 = g.length   # s1 = 5
s2 = g.size     # s2 = 5  (lengthと同じ)
 
 

文字列

ダブルクオートはバックスラッシュ記法と式展開がされる
シングルクオートはバックスラッシュとシングルクオート以外では特殊処理はない
ダブルクオートのかわりに %!~! でくくる方法と、 $Q!~! でくくる方法がある
シングルクオートのかわりに %q!~! でくくる方法がある
文字列は複数行にわたって(改行文字を含めて)書ける
"abcd\n"  # \n は改行文字と解釈される
'abcd\n'  # \ は \のまま
'abcd\\n' # 上記と同じ
%!abcd\n!
%Q!abcd\n!
%q!abcd\n!
"abcd
"        # クオートが閉じるまでの改行文字も含められる
 

文字列の式展開

文字列中に #{ ~ } でくくったところが式展開される
s = "kkk"
print "abc#{ s }\n"    # abckkk と出力される
print "abc#{ "defg" }\n" # abcdfg と出力される
 
print "abc#{ "jfk" # コメントも含められる、行末までコメント化
   }\n"            # なので閉じる} は次行に
 
 

ヒアドキュメント

<<識別子 でヒアドキュメントを書ける、識別式のみの行で終わる
識別子のみもしくは識別子をダブルクオートでくくると、バッククオート記法や式展開がされる
識別子をシングルクオートでくくるとバッククオート記法や式展開がされない (ただし、どちらも終端の識別子をくくってはダメ)
print <<EOS # 次の行からEOSまでヒアドキュメント
this is a pen
that is a pen
what is a pen
EOS
 
#引数にヒアドキュメントを渡せる
func(a, <<EOS, b, c) # 次の行からEOSまでヒアドキュメント
This is a pen
That is a pen
EOS
 
func(a, <<FOO, <<BAR, c) # 複数のヒアドキュメントをかける
This is a pen
FOO
That is a pen
BAR
 
2.times {
   print <<-EOS  # -記号をつけるとヒアドキュメントの終端のインデントが出来る
This is a pen
   EOS
}
 
print <<EOS.upcase # ヒアドキュメントからメソッドを呼ぶことも可能 THIS IS A PEN になる
this is a pen
EOS
 
 

if文unless文

if文は式が真のとき、unless文は式が偽のとき実行される
unless文でelsifは使えない
# 例1
if a>=0 then
   print "a>=0\n"
elsif a<-5 then
   print "a<-5\n"
else
   print "-5<=a<0\n"
end
 
# 例2 aが0以上のときaを出力
print a if a>=0
 

複数分岐case(他言語のswitch文相当)

注:他言語のswitchのようなbreak文はない
arr = [20,30,50]
case a
when 0 .. 2
   print "a is 0 ~ 2"
when 3 .. 5
   print "a is 3 ~ 5"
when 7,9,11
   print "a is 7 9 11"
when *arr
  print "a is menber in arr"
else
   print "else"  # 他言語switch文のdefault相当
end
 

while文until文

while文は式が真のとき、until文は式が偽のとき
# 例1
i = 0
while i>10
   i += 1
end
 
# 例2
i = 0
begin
  i += 1       # 少なくとも1回 i+=1 が実行される
end while i>10
 
 

for文

# 例1
for i in [1, 2, 3]
   print i
end
 
# 例2
for i,j in [[1, 2], [3,4], [4,5]]
    print i, j
end
 

ループ内ジャンプbreak,next,redo (他言語のbreak,continue相当)

for文やwhile文やuntil文やイテレータ文で使える
break はループ脱出 (case文では使えないので注意)
next は次のループ (他言語のcontinue相当)
redo は現在のループを最初から(条件チェックはしない)
breakとnextはイテレータのyieldの戻り値の引数をつけることができる(省略時はnil)
break val
next val

例外捕捉begin-rescue-ensure (他言語のtry-catch-finally相当)

例外は $! か、 =>変数 で取得できる
begin
    ~何か処理
rescue HogeError => evar
    p evar    # 両方ともエラーのタイプが入る
    p $!
    retry     # retryは このbegin節を最初からやりなおす、rescue内でのみ使える
else# elseは 例外が発生しなかったときだけ処理される
ensure# 他言語finally相当、最後に必ず実行される
end
 

例外発生raise

raise "message"
raise fooexception
raise HogeError, "message" # StandardErrorのサブクラスのエラーを投げれる
 

前処理BEGIN

全てのプログラム実行の前段階で処理される
BEGINはトップレベルでしか書けない(ネスト内で書いてはダメ)
BEGIN節が書かれた順番でBEGIN節が処理される
BEGIN {}
 
BEGIN {}
 

終了処理END,at_exit

プログラム実行時に登録される終了時処理(プログラムの終了時に実行される処理)
ネスト内に書くことも可能
END節の実行順は最後に登録されたものからになる(登録順と逆順)
ENDとat_exitの違いはat_exitはループの繰り返しごとに登録されるが、ENDは最初の一回のみ登録される
実行時登録なので実行時に到達しないEND節やat_exitは当然ながら登録されない
END {}
 
for i in [1, 2, 3] {
  at_exit {}         # ループごとに登録される
  END {}             # 最初のループのときのみ登録される
}
 
if false
  END {}             # 到達しないので登録されない
end
 

ブロック付きメソッド呼び出し(イテレータ等の呼び出し)

これは[1,2,3]の配列のクラスのeachというメソッドがyieldを使って定義されている(かな?)
[1,2,3].each do |i|
   print i
end
 
[1,2,3].each { |i|
   print i
}
 
pobj = proc {|i|
  print i
}
[1,2,3].each(&pobj)
 

yield(イテレータの定義にも使われる。ループのループカウンタを生成するみたいな感じ?)

# 例1
def foo
  yield 10
  yield 20
  yield 30
end 
 
foo { |i|
  print i   # 10 20 30と順に出力される
}
 
# 例2
def bar
  yield(1, 2)
  yield(3, 5)
end
 
bar { |a, b|
  print a + b   # (1+2=)3 (3+5=)8 が順に出力される
}
 
# 例3
 
def baz(arr) 
  idx = 0
  while idx < arr.size
    yield(arr[idx] * 2)
    idx += 1
  end
end
 
baz([1,2,3]) {|i|
  print i             # 2 4 6 が表示される
}
 
 
 


minとmax

他の言語のようなminやmaxは存在してない
Enumerableにminとmaxが実装されているので
例えば aとb の小さいほうを取得なら [a,b].min とaとbを配列というEnumerableにして最小を取る
これならば [a,b,c,d].min なども出来るので便利といえば便利
maxについても同様
最終更新:2015年09月05日 01:32