はじめに
Qiita初投稿です!
Rubyの勉強を始めてもうすぐ1ヶ月になります。サンプルコードだけでなく、自身でロジックを考えながら書くようになってきました。そんな中、他の言語ベースの知識と混同していた事があったため共有と自身の備忘録も兼ねて残しておきたいと思います。
配列とは?
以下のように大括弧[]に囲まれた要素をカンマで区切ったものを言います。
array = [123, '文字列', true, nil]
また、多次元配列で要素を格納することもできます。
nest = [[123, 'りんご', true], [456, 'ぶどう', false], [789, 'いちご', false]]
問題のコードと検証
今回やりたかったこと
2つの配列があり、それらを比較して1つでも一致した時はtrue、1つも一致しなかった時はfalseを返したかったため、以下のように書いていました。
if !!([1, 2, 3] & [1, 2, 3]) #=> true
if !!([1, 2, 3] & [4, 5, 6]) #=> falseのはず?
ここで使用している&はビット演算のANDをしています。
!!はtrueかfalseのみを返すために使っています。
!ひとつでは元の状態から反転した状態で真偽値が返ってくるので、それをさらに反転させることで元の値をtrueかfalseのみで返すようにしたい時に使います。
irbに入れて結果を確認してみよう
irb(main):001:0> !!([1, 2, 3] & [1, 2, 3])
=> true #わかる
irb(main):002:0> !!([1, 2, 3] & [4, 5, 6])
=> true #わからないw
irbは対話型評価環境(REPL:Read-eval-print loop)です。
Rubyをインストールしている場合、デフォルトで入っています。
ターミナルやコマンドプロンプトで「irb」と入力して実行することで起動します。
なぜ空配列はtrueが返るのか?
今回のケースでは、以下のRubyにおける真偽値の扱いを知っておく必要がありました。
- Rubyではfalseとnil以外は全て真
、つまりtrueとして扱われる。 - 空配列は、大括弧の中身は空であるものの、
配列そのものは存在しているのでtrueが返るnilでもfalseでもないので真になってしまう。
なぜ空配列はfalseになると決めつけていたのか?
以前、Pythonでスクレイピングをしていたときにlistを扱っており、Rubyの配列に似た構造を持っていたため、Pythonの時と同じように空の配列はfalseが返ってくるはずと安易に考えていたことが原因でした。
以下、Google Colaboratoryでの実行例です。
listに何か入っている場合
list = ['なにか', '入っている']
if list:
print('あるよ')
else:
print('ないよ')
# =>あるよ
listに何も入っていない場合
list = []
if list:
print('あるよ')
else:
print('ないよ')
# =>ないよ
どうすれば良かったのか?
解決したコード
any?メソッドを用いて、全ての要素が偽である場合にfalseを返すようにしました。
[1, 2, 3].any? { |element| [4, 5, 6].include?(element) }
そもそもの学習の進め方について
つよつよエンジニアの人の中には、
- プログラミング言語の違いは方言の違い
- 書き方が少し違うだけだから、他の言語を使えるならすぐ覚えられる
- 難しいところは特にないし、すぐ出来るようになる
などと、こちらの気持ち、感覚とは逆のことを言ってくる人がいたりします。そういった言葉を鵜呑みにしてすぐに習得できるものだと勘違いしたり、技術書を早く読み終えて学習を終わった事にしようとしたり、オリジナルコードを書かずにサンプルコードを試して分かった気になっていたりすると今回の私のようになります。
つまり、基礎をしっかりと築き上げるために、言語の差分の理解に努められるようになるまでは、技術書を使い最初から最後まで体系的に学び、小さくても良いのでオリジナルコードを書いて試すことをおすすめします。
あとがき
今回の失敗は、こうなるだろうという思い込みが招いた結果でした。他の言語ではこう書いていたからなどと考えずに、流用して良い知識とダメな知識をしっかりと使い分けていきたいと思います。
最後に誰もが知っているであろう名言で終わりたいと思います。
「プログラムは思った通りには動かない。書いた通りに動くのだ。」
うっ…、頭が…。