あくまでメモ用です。
間違った解釈等あればコメントの方で教えていただければ修正いたします。
<=>演算子について
<=>演算子を定義するクラスは一般にComparableモジュールをミックスインとしてインクルードする。
ミックスインについて理解できていないため、下記記事を参考にしてみます。
今更聞けない! Ruby の継承と mixin の概念を継承リストから学ぶ
to_〇〇について
明示的な変換
- to_s ... Stringへの変換 (Object型のinspectはto_sを呼び出す)
- to_i ... Integerへの変換
- to_f ... Floatへの変換
- to_a ... Arrayへの変換
- to_c ... Complexへの変換
- to_r ... Rationalへの変換
暗黙の変換
以下は暗黙の変換をさせても良いときに実装する。
実装していない場合は、暗黙の型変換は行われない。
- to_int ... Integerへ
- to_ary ... Arrayへ
- to_hash ... Hashへ
- to_str ... Stringへ
式展開された変数
""の中で式展開された変数は自動的にStringに変換される。
フリーズ系
- s.freeze ... sをイミュータブルにする。(イミュータブル)
- s.frozen? ... sがフリーズされているか調べる。 文字列ならば、
s = 'string'
s.freeze
s.frozen? # true
s2 = +s # 凍結されていた場合、凍結状態の文字列の凍結されていないものを複製して返す
s2.frozen? # false
文字列の単項演算子(+)を用いることで、凍結状態のものと同じ文字列を持った凍結されていない文字列を作成することができる。
汚染
- s.taint ... sに汚染済みマークを付ける
- s.tainted? ... sが汚染されているか調べる
- s.untaint ... sの汚染済み状態を外す
ユーザ入力等は自動的に汚染マークを付けられる。
オブジェクトのコピー
clone,dup
- clone ... オブジェクトの凍結状態、汚染状態、信頼状態、特異メソッドをコピーする.
- dup ... 汚染状態と信頼状態をコピーするが、凍結状態、特異メソッドはコピーしない.
浅いコピー
オブジェクト内に持っているインスタンス変数等もコピーされるが、指す先は同じものであるため、
コピー先で破壊的なメソッドを呼び出すとコピー元も変更される。
変数への代入をした際の識別子の扱い
class example
def x; 1; end # 必ず1を返すxという識別子のメソッド
def test
puts x # 上のメソッドを呼び出す
x = 0 if false
puts x # nilが出力
x = 2
puts x # 2
end
end
上記のように、識別子に対する代入を検出していれば、その識別子をローカル変数として扱う。
多重代入の注意点
puts x,y=1,2 # 1,2とは出てくれない。(xとy=1と2を出力しようとする。)
puts ((x,y=1,2)) # 1,2と出る!
フリップフロップ
[1,2,3,4,'string',5,6].each do |x|
print x if x==3..x==5
end
こんなの。左辺がtrueになると、右辺がtrueになるまで左辺が評価されず、右辺の評価が続く。
この場合、34string5
という出力となる。
シンボル
":"から始まるもの。
Rubyでは、メソッド名やクラス名、メンバ名、定数名などを数値で管理しており、その整数をコード上で表現したのがシンボル。シンボルと数値は1対1対応している。
速度が早いため、ハッシュのキーなどにすると良い。
respond_toメソッドは引数に指定したメソッドを持っているか調べるメソッド。
'str'.respond_to? :length # true
'str'.respond_to? :a # false
hash = { one: '1', two: '2' }
p hash[:one] # "1"
参考記事
Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい
ヒアドキュメント
イメージでは、書いたまんまに使える文字列
下記のように書くとダブルクォーテーションで文字列を囲っている時と同じように、エスケープ文字を許容する。
puts <<EOS
line1
line2
EOS
puts "line1\nline2"
と同じ
逆に、エスケープ文字を認めたくないときには、上記でいう、EOS のようなセレクタをシングルクォーテーションで囲ってやるとできる。
puts <<'EOS'
\t\t\t\t
aaaaa
EOS
puts '\t\t\t\t';puts 'aaaaa'
と同じ
定数の扱い
Rubyの定数はデフォルトでは変更可能であるため、freezeするのが好ましい。
(freezeしないと、Warningは出るものの、再代入する際に値を変えることができてしまう。)
参考記事
オブジェクトの等価性
equal?
メソッド
2つのオブジェクトが同一のオブジェクトを参照しているか確かめるもの。
str1 = 'string'
str2 = 'string'
str1.equal? str2 # false
==
演算子
Object型では、2つのオブジェクトのオブジェクト参照が等しいかどうかを確かめるためのもの。(equal?と同じ)
ほとんどのクラスでは、インスタンスは別でも値が等しいかテストできるように定義し直されている。
※!=
は==
演算子の実行結果を反転する。(==
を実装していれば!=
は使える。)
str1 = 'string'
str2 = 'string'
str1 == str2 # true
ArrayクラスやHashクラスにも==
演算子は実装されており、等価とみなされる場合は、
Array
- 要素の数が同じ
- 対応するペアがどれも
==
で等しい場合
Hash
- キー/値のペアの数が同じ
- 対応するキーの値がそれぞれ等しい場合
※値は==
演算子で比較されるが、ハッシュキーはeql?
メソッドで比較される。
eql?
Object型ではequal?
の同義語として実装されている。
このメソッドをオーバライドしているクラスは型変換をしない厳格な意味での==
として用いることが多い。
1 == 1.0 # true
1.eql? 1.0 # false
===
演算子
「case演算子」と呼ばれる。
Object型:==
演算子を呼び出すものとしてのデフォルトの===
演算子を定義している。
多くのクラス:==
の等価と変わらない。
いくつかのクラス:別の形で定義している。以下、その例
(1..10) === 5 # true 1..10の範囲内
/\d+/ === '123' # true 正規表現(Regexpクラス)にマッチしている
String === 's' # true 's'はStringクラスのインスタンス
:s === 's' # false (Ruby2.5の環境下)