Ruby Tips!

RubyのTipsを紹介します

配列から要素を検索する

配列にある要素が含まれているかを判定するにはArray#include?を使う。このメソッドは引数で与えた要素と==で等しい要素が存在する場合にtrueを返し、存在しない場合はfalseを返す。

p [1, 2, 3].include?(2) #=> true
p [1, 2, 3].include?(4) #=> false

何処に含まれているかも調べたい場合はArray#indexを使う。このメソッドは引数で与えた要素と==で等しい要素を最初に見つけたインデックスを返し、要素が存在しなければnilを返す。

p [1, 2, 3].index(2) #=> 1
p [1, 2, 3].index(4) #=> nil

Array#indexはブロックを取ることもできる。この場合はブロックの評価結果が真になる最初の要素を見つけたインデックスを返す。

p [1, 2, 3].index{|v| v % 2 == 0 } #=> 1

Array#indexは配列を先頭から検索するが、配列を末尾から検索するArray#rindexもある。

strftimeメソッドで時刻を文字列に整形する

Time#strftimeは時刻を指定したフォーマットで文字列に変換するメソッドである。フォーマットの文字列として以下が利用できる。

文字 意味
%A 曜日の名称(Sunday, Monday ... )
%a 曜日の省略名(Sun, Mon ... )
%B 月の名称(January, February ... )
%b 月の省略名(Jan, Feb ... )
%C 世紀 (2009年であれば 20)
%c 日付と時刻
%D 日付 (%m/%d/%y)
%d 日(01-31)
%e 日。一桁の場合、半角空白で埋める ( 1..31)
%F %Y-%m-%d と同等 (ISO 8601の日付フォーマット)
%H 24時間制の時(00-23)
%h %b と同等
%I 12時間制の時(01-12)
%j 年中の通算日(001-366)
%k 24時間制の時。一桁の場合、半角空白で埋める ( 0..23)
%L ミリ秒 (000.999)
%l 12時間制の時。一桁の場合、半角空白で埋める ( 0..12)
%M 分(00-59)
%m 月を表す数字(01-12)
%n 改行 (\n)
%N 秒の小数点以下。桁の指定がない場合は9桁 (ナノ秒)
%6N マイクロ秒 (6桁)
%3N ミリ秒 (3桁)
%P 午前または午後(am,pm)
%p 午前または午後(AM,PM)
%R 24時間制の時刻。%H:%M と同等。
%r 12時間制の時刻。%I:%M:%S %p と同等。
%S 秒(00-60) (60はうるう秒)
%s 1970-01-01 00:00:00 UTC からの経過秒
%T 24時間制の時刻。%H:%M:%S と同等。
%t タブ文字 (\t)
%U 週を表す数。最初の日曜日が第1週の始まり(00-53)
%u 月曜日を1とした、曜日の数値表現 (1..7)
%v VMS形式の日付 (%e-%b-%Y)
%V ISO 8601形式の暦週 (01..53)
%W 週を表す数。最初の月曜日が第1週の始まり(00-53)
%w 曜日を表す数。日曜日が0(0-6)
%X 時刻
%x 日付
%Y 西暦を表す数
%y 西暦の下2桁(00-99)
%Z タイムゾーン
%z タイムゾーンUTCからのオフセット (例 +0900)
%:z タイムゾーン。コロンが入ったUTCからのオフセット (例 +09:00)
%::z タイムゾーン。コロンが入った秒まで含むUTCからのオフセット (例 +09:00:00)
%% %自身

オブジェクトを複製する

オブジェクトを複製するにはObject#dupObject#cloneを使う。Object#cloneはオブジェクトの内容だけでなく特異メソッドなどもコピーする。一般的にはObject#dupで十分だ。以下は文字列を複製する例である。

str = "sample string"
def str.singleton_method; end
str.taint
str.freeze

p str #=> "sample string"
p str.respond_to?(:singleton_method) #=> true
p str.tainted? #=> true
p str.frozen? #=> true

str2 = str.dup
p str2 #=> "sample string"
p str2.respond_to?(:singleton_method) #=> false
p str2.tainted? #=> true
p str2.frozen? #=> false

str3 = str.clone
p str3 #=> "sample string"
p str3.respond_to?(:singleton_method) #=> true
p str3.tainted? #=> true
p str3.frozen? #=> true

メソッドを再定義するときaliasで元のメソッドを残しておく

メソッドを再定義するときaliasで元のメソッドを残しておく

あるクラスを継承して既存のメソッドを再定義する場合、元のメソッドにaliasを付けておくと、再定義するメソッドの中で元のメソッドを呼ぶことができる。元のメソッドの機能を活かしつつ、何か機能を追加したい場合に良く使う方法だ。

class SuperClazz
  def method
    puts 'original method'
  end
end

class Clazz < SuperClazz
  alias __method method
  def method
    puts 'preprocessing'
    __method
    puts 'postprocessing'
  end
end

c = Clazz.new
c.method
=begin
preprocessing
original method
postprocessing
=end

タブとスペースを変換する

文字列中のタブとスペースを変換するには、String#gsubによる置換を使って以下のようにする。以下はタブをスペース4つと変換する例である。

p 'hoge\tpiyo\t\tfuga'.gsub('\t', ' ' * 4) #=> "hoge    piyo        fuga"
p 'hoge    piyo        fuga'.gsub(' ' * 4, '\t') #=> "hoge\\tpiyo\\t\\tfuga"

最大公約数・最小公倍数を求める

最大公約数はInteger#gcdで、最小公倍数はInteger#lcmで求めることができる。またInteger#gcdlcmは最大公約数と最小公倍数を同時に求めて配列で返す。

p 624.gcd(735) #=> 3
p 624.lcm(735) #=> 152880
p 624.gcdlcm(735) #=> [3, 152880]

なおRuby 1.8ではこれらのメソッドはrationalライブラリで拡張されているため、rationalライブラリをrequireする必要がある。

2進、8進、10進、16進数を相互に変換する

文字列を数値に変換する

2進数などで書かれた文字列を数値に変換するにはKernel.#IntegerまたはString#to_iを使う。String#to_iは基数が指定できるため、文字列に0xなどの接頭子が無くても数値に変換することができる。

p Integer("0b11111111") #=> 255
p Integer("0377") #=> 255
p Integer("255") #=> 255
p Integer("0xFF") #=> 255

p "11111111".to_i(2) #=> 255
p "377".to_i(8) #=> 255
p "255".to_i(10) #=> 255
p "FF".to_i(16) #=> 255

数値を文字列に変換する

数値を2進、8進、10進、16進数の各文字列に変換するには、String#%を使って以下のようにする。これはKernel.#sprintfと同じである。bは2進数、oは8進数、dは10進数、xは16進数を示すフォーマット文字列だ。

p "%#+b" % 255 #=> "+0b11111111"
p "%#+o" % 255 #=> "+0377"
p "%#+d" % 255 #=> "+255"
p "%#+x" % 255 #=> "+0xff"