IQ1450で美少女JSの先輩「
存在しないローカル変数の参照について
Rubyでは存在しない変数名を参照しようとするとエラーになります。
p sugoi
#=> NameError: undefined local variable or method `sugoi' for main:Object (NameError)
kanari = totemo
#=> NameError: undefined local variable or method `totemo' for main:Object
この点について疑問に思う方は居ないかと思います。
それを前提に、今日はRubyで無から有を生み出す方法をお伝えしましょう。
以下の縛りを導入します。
- 一度宣言・初期化した変数は他の式・文で使用しない
- 演算子および演算子風のシンタックスシュガーが導入されたメソッド、及び代入、また括弧のみが使用できる
true
、false
の生成
true
、false
を生成します。上記縛りを守ったままこれを達成することは可能でしょうか?
t = !t
p t #=> true
f = !!f
p f #=> false
可能です。
不思議ですね、一体何が起こったのでしょうか。
これは、変数に値を代入するようなコードをパーサが読んだ瞬間、その変数がnil
で初期化されるという仕様を悪用したコードです。
true
の生成の例で解説すると、代入の左辺をパーサが読んだ段階で変数t
がnil
で初期化されるため、右辺の!t
を評価することは!nil
を評価することと同義です。
!nil
の評価結果はtrue
となるので、変数t
にはtrue
が代入されることとなります。
false
の例も同じで、!!nil
がfalse
であることを利用しています。
整数の生成
次に整数を生成してみましょう。
zero = zero <=> zero
p zero #=> 0
one = (one <=> one) ** (one <=> one)
p one #=> 1
いいですね。nil.to_i
は0
となりますが、メソッドを使用すると面白くないということで採用した縛りにより、メソッドについては演算子風のシンタックスシュガーが導入されたものしか使用することができません。そこで<=>
メソッドを使用することで0
を得ることにしました。
0
を得ることができれば1
も得られます。同じ要領で0
を二つ生成し、**
メソッドによって0の0乗を求めます。1です。
0と1があればあとは任意の整数が生成可能なので、そこは省略します。
まとめ
というわけで、皆さんもRubyで無から有の生成をやってみてください。業務には一切役に立たないと思います。
-
Symbol
を生成する方法 -
Array
を生成する方法 - できるだけ無を用いてFizzBuzzをアレする方法
などは読者への課題とします。
」
ぼく「なるほど」