URubyリリース!
Merry Christmatz!!*1
今年もクリスマスRubyの季節がやって来ました。今回のRubyは「U」です。
・・・
RubyとSmalltalkの関係についてはいろんな受け取り方があるようですが、利用感がなんとなく似てるのは事実でしょう。しかし我々Rubyistにとっては残念なことに、フリーダムさという点でRubyはSmalltalkに一歩劣ると言わざるを得ません。
例えばSmalltalkにはSmalltalk環境自身を表す"Smalltalk"というのグローバル変数があります。これは変数ですから値を再代入できます。Squeakを持っている人は"MVC Project"を開き*2、ワークスペースで次の様に入力してください。
ポチッ(Command+d)とな。
・
・
はい、実行するとフリーズしてなにも反応が帰って来なくなりますので、Squeakを強制終了してください。
このようにSmalltalkは自らの意志でいっさいを虚無に帰して消え去ることさえ許しているのです。自由に生きることは言い換えれば自由に死に方を選べるということ。これこそがSmalltalkにおける自由の象徴といえるでしょう。
そんな自由がRubyにも欲しいと思いませんか?
Rubyにも喫茶なんかじゃない、本当の自由を。
・・・
http://github.com/technohippy/uruby
という訳でURubyを作りました。UはUndefです。URubyではクラスにnilを代入することでそのクラスを(擬似的に)なかったことにできます。
class Parent def greeting puts "hello" end end class Child < Parent end child = Child.new child.greeting #=> "hello" Parent = nil child.greeting #=> undefined method `greeting' for #<Child:0x...> (NoMethodError)
nilが代入されたクラスのメソッドは一切呼べません。nilだからnewできませんし、継承したクラスも定義できません。さらに親クラスのinitializeが呼び出される子クラスもnewできません。
Fixnum = nil 1 + 1 #=> undefined method `+' for 1:Fixnum (NoMethodError)
Array = nil a = [1,2,3] a[0] #=> undefined method `[]' for [1, 2, 3]:Array (NoMethodError)
リテラルはなかった事にはできないけど、とりあえず何にもできなくなります。
Object = nil puts "hello" #=> undefined method `puts' for #<Object:0x...> (NoMethodError)
Object = nil class Parent; end #=> Object does not exists. (RuntimeError)
Object = nilするとputsを含むいわゆる関数は全部使えなくなります。もちろんObject由来のメソッドは全部使えません。親クラス指定なしのクラスも定義できません。
あとこれは完全におまけだけど
RubyVM = nil
とするとその場でフリーズします。フリーズというかスリープ。
ということで、2010年のクリスマス、Rubyistは本当の自由を手に入れることができました。
Merry Christmatz!!
URubyの作り方
ホントは他に作りたいものがあったんだけど、どうしても動かなくて諦めました。間に合わせででっち上げたのでかなり手抜き・・・。
variable.c
static void mod_av_set(VALUE klass, ID id, VALUE val, int isconst) { // ..snip.. if ((VALUE)value == Qundef) autoload_delete(klass, id); else if (val == Qnil) { autoload_delete(klass, id); rb_funcall(value, rb_intern("undef_class"), 0, 0); } else rb_warn("already initialized %s %s", dest, rb_id2name(id)); // ..snip.. }
定数にnilが代入されたときにundef_classメソッド呼ぶだけ。最初はst_delete(rb_class_tbl, id, 0);とかやろうとしたけど落ちまくるので・・・。
undef_classの実装はprelude.rbの中。
prelude.rb
class RubyVM def self.undef_class sleep exit end end class Object def self.undef_class eval %Q{ def self.inherited(subclass) raise "#{self.name} does not exists." end } self.included_modules.each do |mod| (mod.singleton_methods - [:raise]).each do |m| undef_method m end end (self.instance_methods - (self.superclass.instance_methods rescue [])).each do |m| undef_method m end undef_method :initialize define_method :initialize do raise "#{self.name} does not exists." end end end
うん。ショボイね。来年はもうちょっと頑張るよ。