case式での一般的なRangeオブジェクトの使い方
Cool!に書けますよねー
range_case.rb
def range_case(year)
case year
when 1912..1926
"T"
when 1926..1989
"S"
else
"H"
end
end
range_case(1926) # => "T"
range_case(1973) # => "S"
range_case(2012) # => "H"
case式でRangeオブジェクト同士の比較には気を付けて
Range(, Regexp, Module)オブジェクト同士の比較にcase式は使わない方がイイかも?Cool!な書き方によるトラップ
strange_case.rb
def strange_case(obj)
case obj
when obj
true
else
false
end
end
strange_case( "1" ) # => true
strange_case( :"1" ) # => true
strange_case( 1 ) # => true
strange_case( [1, 2, 3] ) # => true
strange_case( {"1"=>1} ) # => true
strange_case( (1..3) ) # => false
strange_case( /.*/ ) # => false
strange_case( Fixnum ) # => false
なので、ArrayオブジェクトはRangeオブジェクトのようにはならないよね
Arrayオブジェクトでも「*」で展開すればOKですけど、そのままでは上の例の通りNGです。
array_case.rb
def array_case(year)
case year
when [*1925, 1926]
"T"
when [*1926..1989]
"S"
else
"H"
end
end
array_case(1926) # => "H"
array_case(1973) # => "H"
array_case(2012) # => "H"
ArrayオブジェクトもRangeオブジェクトと同じ仕組みを持たせれば同様な動きになるよ
ArrayをオープンしてRange#include?と同様にArray#include?のエイリアスにArray#===を追加する
「*」で展開しなくてもOKになる
ex_array_case.rb
class Array
alias :=== :include?
end
def ex_array_case(year)
case year
when [*1925, 1926]
"T"
when [*1926..1989]
"S"
else
"H"
end
end
ex_array_case(1926) # => "T"
ex_array_case(1973) # => "S"
ex_array_case(2012) # => "H"
でも、当然弊害でるよ
Arrayオブジェクト同士の比較もNGに。
Range#include?のエイリアスにRange#===があるのに、Array#include?のエイリアスにArray#===がないのは何故?って思ってたけど、これが理由なのかな?
arara_case.rb
require './strange_case.rb'
strange_case( "1" ) # => true
strange_case( :"1" ) # => true
strange_case( 1 ) # => true
strange_case( [1, 2, 3] ) # => false
strange_case( {"1"=>1} ) # => true
strange_case( (1..3) ) # => false
strange_case( /.*/ ) # => false
strange_case( Fixnum ) # => false