Ruby データ型キャスト
Ruby プログラミングにおいて、データをあるデータ型(Data Type)から別のデータ型へコンバート(Convert)する必要に迫られる場面は頻繁に発生します。特定のデータ型が要求される算術オペレーション(Arithmetic Operations)を実行するためであれ、特定のフォーマットでデータをディスプレイするためであれ、これは不可欠なスキルです。
データ型間でどのようにキャスト(Cast)を行うかを理解することは、プログラムが正確かつ高効率にラン(実行)されることを保証します。
本章では、Ruby における一般的なデータ型キャストを網羅し、データを効果的にハンドリングするために必要な知識とツールを提供します。
1. エクスプリシット・キャスト
エクスプリシット・キャスト(明示的な型変換、Type Casting とも呼ばれます)とは、特定のビルトイン・メソッド(Built-in Methods)を使用し、意図的に値をあるデータ型から別のデータ型へコンバートすることを指します。Ruby はこの目的のために、非常に便利なビルトイン・メソッドをいくつか提供しています。
1.1 インテージャーへのコンバート (to_i)
to_i メソッドを使用して、他のデータ型をインテージャー(Integer:整数)にコンバートできます。
ストリングからインテージャーへ: ストリング(String)をインテージャーにコンバートする際、Ruby はそのストリングをパース(Parse)し、インテージャーの値をエクストラクト(抽出)しようと試みます。ストリングが有効なインテージャーを表していない場合、to_i は 0 をリターンします。
string_num = "123"
integer_num = string_num.to_i # "123" をインテージャーの 123 にコンバートする
puts integer_num # アウトプット: 123
string_with_text = "456abc"
integer_from_text = string_with_text.to_i # "456abc" をインテージャーの 456 にコンバートする (最初の非数値キャラクターに遭遇した時点でストップする)
puts integer_from_text # アウトプット: 456
invalid_string = "abc"
integer_from_invalid = invalid_string.to_i # "abc" をインテージャーの 0 にコンバートする (有効なインテージャーのストリングではないため)
puts integer_from_invalid # アウトプット: 0フロートからインテージャーへ: フロート(Floating-point number)をインテージャーにコンバートする際、Ruby は小数部分を直接トランケート(切り捨て)します(最も近いインテージャーへの切り捨てと同等です)。
float_num = 3.14
integer_num = float_num.to_i # 3.14 をインテージャーの 3 にコンバートする
puts integer_num # アウトプット: 3
another_float = 5.99
another_integer = another_float.to_i # 5.99 をインテージャーの 5 にコンバートする (注意:四捨五入はされない)
puts another_integer # アウトプット: 51.2 フロートへのコンバート (to_f)
to_f メソッドは、他のデータ型をフロート(Floating-point numbers)にコンバートするために使用されます。
ストリングからフロートへ: インテージャーへのコンバートと同様に、Ruby はストリングをパースしてフロートの値をエクストラクトしようと試みます。ストリングがイリーガル(無効)な場合、to_f は 0.0 をリターンします。
string_float = "3.14"
float_num = string_float.to_f # "3.14" をフロートの 3.14 にコンバートする
puts float_num # アウトプット: 3.14
string_with_text = "2.71abc"
float_from_text = string_with_text.to_f # "2.71abc" をフロートの 2.71 にコンバートする (小数点以降の最初の非数値キャラクターでストップする)
puts float_from_text # アウトプット: 2.71
invalid_string = "abc"
float_from_invalid = invalid_string.to_f # "abc" をフロートの 0.0 にコンバートする
puts float_from_invalid # アウトプット: 0.0インテージャーからフロートへ: インテージャーをフロートにコンバートする場合は、単に数値の後に小数部分 .0 が追加されます。
integer_num = 10
float_num = integer_num.to_f # 10 をフロートの 10.0 にコンバートする
puts float_num # アウトプット: 10.01.3 ストリングへのコンバート (to_s)
to_s メソッドは、他のデータ型をストリング(String)にコンバートします。ナンバーやブーリアン(Boolean)をテキストとコンカチネート(結合)したい場合に、このメソッドは特に有用です。
インテージャー / フロートからストリングへ:
integer_num = 42
string_num = integer_num.to_s # 42 をストリングの "42" にコンバートする
puts string_num # アウトプット: 42
puts string_num.class # アウトプット: String
float_num = 2.71
string_float = float_num.to_s # 2.71 をストリングの "2.71" にコンバートする
puts string_float # アウトプット: 2.71
puts string_float.class # アウトプット: Stringブーリアンからストリングへ:
bool_true = true
string_true = bool_true.to_s # true をストリングの "true" にコンバートする
puts string_true # アウトプット: true
puts string_true.class # アウトプット: String
bool_false = false
string_false = bool_false.to_s # false をストリングの "false" にコンバートする
puts string_false # アウトプット: false
puts string_false.class # アウトプット: String1.4 シンボルへのコンバート (to_sym)
to_sym メソッドは、ストリングをシンボル(Symbol)にコンバートします。シンボルはイミュータブル(不変)であり、メモリ上に常駐するストリングのようなもので、通常はハッシュ(Hash)のキーや識別子(Identifier)として使用されます。Ruby はメモリ内に各シンボルのコピーを1つだけ保持するため、特定のケースではシンボルを使用することでパフォーマンスが向上します。
string_name = "name"
symbol_name = string_name.to_sym # "name" をシンボルの :name にコンバートする
puts symbol_name # アウトプット: name
puts symbol_name.class # アウトプット: Symbolまた、to_sym のエイリアスである intern メソッドを使用することも可能です:
string_status = "status"
symbol_status = string_status.intern # "status" をシンボルの :status にコンバートする
puts symbol_status # アウトプット: status
puts symbol_status.class # アウトプット: Symbol2. インプリシット・キャスト
インプリシット・キャスト(暗黙的な型変換、Type Coercion とも呼ばれます)とは、特定のコンテキストにおいて自動的に発生するコンバートを指します。Ruby はオペレーションを実行するために、バックグラウンドでデータ型のコンバートを試みます。しかし、他のいくつかの言語と比較すると、Ruby のインプリシット・キャスト機能は限定的です。通常、コードの明確性を保ち予期せぬ挙動を回避するためには、エクスプリシット・キャストを使用することがベストプラクティスです。
2.1 ストリング・インターポレーションにおけるインプリシット・キャスト
前の章で遭遇したかもしれませんが、ストリング・インターポレーション(String Interpolation)は実際にはインプリシット・キャストの一形態です。#{} シンタックスを使用してバリアブル(Variable)をストリング内にエンベデッド(埋め込み)する際、Ruby は自動的にそのバリアブルの to_s メソッドをコールし、ストリングへとコンバートします。
age = 30
puts "私は今年 #{age} 歳です。" # インテージャーの 30 がインプリシットにストリングへコンバートされる
# アウトプット: 私は今年 30 歳です。
price = 19.99
puts "プライスは ¥#{price} です。" # フロートの 19.99 がインプリシットにストリングへコンバートされる
# アウトプット: プライスは ¥19.99 です。2.2 オペレーターの挙動と注意事項
特定のケースにおいて、Ruby のオペレーターはインプリシット・キャストをトリガーします。しかし、この挙動は予測不可能な場合があり、不用意に扱うとバグの原因となるため、十分に注意してください。
エクスプリシット・キャストを行わずにストリングとインテージャーを加算(+ を使用)しようとすると、Ruby は TypeError エラーをスローします。
# 正しいアプローチ:エクスプリシット・キャスト
puts "アンサーは " + 42.to_s # アウトプット: アンサーは 42
# 誤ったアプローチ:TypeError エラーがスローされる (no implicit conversion of Integer into String)
# puts "アンサーは " + 42