これで最後。
情報源
PythonからRubyへ
細かい記法まで含めたらかなり多いと思う。
Pythonとの類似
とくに気になるところはなかった。
Pythonとの違い
- 定数をつくれます
- 名前付けについての規約がいくつかあります
- リストコンテナは、配列しかありません。配列は可変です
- テキスト展開の記法が違います
- 属性には直接アクセスできません
- 組み込みクラスにメソッドを追加したり、書き換えたりできます
- 一度定義した変数を未定義にする方法はありません
yield
キーワードの振る舞いは異なります- 無名関数は3種類ある
定数をつくれます
(値が変更されることを期待しない変数)
値が変更されると警告が出るだけ。実際は変更されてしまうので定数とはとても言えない代物。
Rubyの規約としては名前の頭文字を大文字にすると定数になる。必ずしも守る必要のない命名規則としては、見やすさをかねて全文字を大文字にするのがよい。
MAX = 100 MAX = 999
warning: already initialized constant MAX warning: previous definition of MAX was here
> p MAX 999
変更されてしまう。これ定数じゃないよね。警告なんて流しちゃうだろ。かといって実行時エラーにされても大事になりすぎるのかな。
テキスト展開の記法が違います
二重引用符で囲まれた文字列は、エスケープシーケンス(\tなど)や、 式展開(いちいち+で文字列連結すること無しに、 Rubyの式を評価した結果を他の文字列に挿入可能にするしくみ)を解釈します。 一重引用符で囲まれた文字列は、Pythonでいうraw文字列と同じ扱いとなります。
言語 | 展開しない | 展開する |
---|---|---|
Ruby | '' |
"" |
Python | r'' , r"" |
'' , "" |
属性には直接アクセスできません
Rubyでは、属性へのアクセスはすべてメソッド経由になります
あれ? attr_accessor
があったよね?
class C attr_accessor :name def initialize @name = 'ytyaru' end end p C.new.name = 'YTYARU' #=> "YTYARU"
アクセスできちゃってますけど? それともattr_accessor
ってやつもメソッドなの?
なるほど。メソッドを作る糖衣構文だったのか。attr_accessor
を使わずに書くと以下のようになると。
class C def name; @name; end def name=(v); @name=v; end def initialize @name = 'ytyaru' end end p C.new.name = 'YTYARU' #=> "YTYARU"
これでゲッター、セッターが書けるらしい。def name=(v)
っていうところがセッターだね。クセのある記法だけどPythonよりはずっとマシ。できればC#くらいスマートだと嬉しかったけどね。
ゲッターとセッターは以下の糖衣構文がある。
class C attr_reader :name attr_writer :name end
読取専用にしたいときはattr_reader
だけセットするとか、そういった使い方になる。
一度定義した変数を未定義にする方法はありません
Pythonでいう
del
のように
ふーん、そうなんだ。
変数をnilで設定すれば、変数に入っていた値をGCできるようにはできますが、 スコープが存在する限り変数自体はシンボルテーブルに残り続けます。
C#とかもそんな感じだったはず。
yield
キーワードの振る舞いは異なります
Pythonでは、関数呼び出しの外側のスコープへ実行結果を返します。 そのため、外側のコードは処理の再開について責任を負います。 Rubyでは、yieldは最後の引数として渡された別の関数が実行されます。 そして、実行が完了すると処理を再開します。
最後の引数として渡された別の関数
って、ブロックとかProc
のことかな? そのへんよくわからない。
def get yield 1 yield 2 yield 3 end
> get {|i| p i} 1 2 3 => 3
無名関数は3種類ある
Pythonがサポートしている無名関数はラムダ式のみですが、 Rubyはブロック、Procオブジェクト、ラムダ式といった種類の無名関数があります。
概念 | 概要 |
---|---|
ブロック | クロージャ。普段参照できないローカル変数を参照できる。 |
Proc | 変数に代入できるブロック。& はブロックとオブジェクトを相互変換する。 |
Lambda | Procとほぼ同じ。lambda? で真が返る。call でreturn されてもメソッド終了しない。余分な引数があるとエラーになる。 |
ProcよりもLambdaを使ったほうがバグが少なくなるはず。
所感
無名関数のところが難しい。自分でコードを書ける自信がない。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
- Ruby 3.0.2
$ uname -a Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux