Rubyの変数とスコープについて
寒いですね。ろんです。
最近ヒットした自炊メニューはハンバーグです。
今晩はいい加減写経も飽きてきてしまったので、Rubyの言語仕様について触れてみようと思います。今回は変数とスコープについて、Javaをなんとなく触れていた時期と比べてメモっておきます。
Rubyのメンバとは
Rubyの変数にはJavaのようにデータタイプの修飾子はなく、暗黙的に代入時のデータを解釈してくれるようです。
また、Rubyの定数は再代入が可能です。ここもJavaとは違うところですね。
そもそもClassが定数として扱われるという性質があり、
メイン宣言(メソッド、メンバを呼び出すフィールドのようなもの)が関数として扱われるJavaとはこちらも違ったところです。同じMVCで設計されているといっても、呼び出し方も違いますね。
その為か、クラスをimportやinterface, overrideなどで多重継承するというよりも、クラスの再オープンや継承が単一クラスの継承で実行されます。
これでは不便なので、mix-inという機能でいろんな機能追加などが可能になるのですが、今回は割愛します。
Rubyの変数たち
勉強を始めた序盤でかなり惑わされ、曖昧になってしまっている部分ですが、
先ほど述べたようにRubyの変数はメンバ宣言が必要なく、修飾子も定義されていません。
主に下記の5つで成り立っています。
ローカル変数 … 代入された位置からブロックもしくはメソッドの終端まで
$グローバル変数 … どこからでも参照ができる
@@クラス変数 … クラスインスタンスから参照が可能
定数 … クラス・モジュール内(内側での宣言も含む)、宣言元を継承もしくはincludeしているモジュール内、外部からはモジュール演算子と宣言されているクラスを表記することでアクセスが可能
ローカル変数はスクリプト言語を学び始めた私にとっては珍妙で、『プログラムは上から下へ降りる挙動をする』という感覚があった為、同一ファイル内で定義されている変数を呼び出そうとした時にName Errorなんて返ってくるので、勝手に理不尽さを感じていました。
こんなにメンバ宣言してしまって…、GCしなくて大丈夫なのかしら…とJavaのコンパイル待ちをしていた時期と比べて開発速度が段違いだった衝撃を思い出します。
話が脱線しましたが、Rubyでのローカル変数はメソッド内での宣言が必要になります。(attr_accesorなどのコンストラクタ類はのぞいて)
グローバル変数は使った事がないのですが、どこからでも参照・更新が出来てしまうという危うさは変わらないようです。freezeを使って再代入出来なくするという手も使えるようですが、各所で話を聞く限り、特異メソッドで定義してあげる方が精神衛生上良さそうな気がします。
インスタンス変数は属しているフィールドのインスタンス内でのみ生存ができるイメージです。正直、メソッドと同名のviewにこやつらが生存している原理に違和感を持ったままですが…
宣言していないのに参照したらどうなるの?
これはクラス変数・定数、一部ローカル変数について例外が発生します。
条件分岐で代入が実行されなかった場合は宣言のみ適用され、後続で参照する事が可能です。
過去に条件の考慮漏れで代入されていないインスタンス変数を参照してしまい、データを作るミスを犯してしまった事があります。
何を集計してどんな出力を行うかにもよるのですが、集計or抽出されたデータにnilが予想される場合、どのような設計を行うのかなあと考えるところです。ログに焼き付けるようにしておくのがベターなのですかね…やった事ないですが。
Javaであれば即刻 IndexOutOfBoundsExceptionやらNullPointerExceptionを投げてくれるので、良い意味で常に危機感と隣り合わせでコーディング出来ますよね。
所感
配列やらを決め打ちでやらずに柔軟に対応してくれるのが助かる!(Vectorもいるけど…)
でもたまにnilに泣かされてます
技術の話ばかりではつまらないので、推しの飲食店をメモることにします。
今回は代々木のトスカーナさん。
コスパ良しでもちもちボロネーゼが評判です。個人的には同じくらいもちもちで焼きたてさっくりなピザ推しなのですが。
ドルチェのオレンジとチョコレートのアイス(料理名失念)も口当たりが良くてサイコーでした。
マサカリお待ちしてまーす🐕