ゆの in 各種言語を Squeak Smalltalk で意訳


とりあえず、Ruby 版、C# 版、Perl 版の三つを翻訳してみました。


ゆの in Ruby

Smalltalk には #attr_* はないので、ハンドコードしないといけません。あるいは IDE の仕事として、クラスブラウザから「create inst var accessors」することで、ゲッター「X>>#a」(と、後述の #new: で必要になるセッター「X>>#a:」)を自動生成させます。

レシーバを省略したメソッド呼び出しはできないので、#_ はメソッドではなくグローバル変数として定義しました。例によって、半角アンダーバーは使えないので全角「_」で逃げました。作業はクラス初期化メソッド「X class>>#initialize」で行なうことにしました。

引数付きのときは #initialize の暗黙の呼び出しは使えないので、クラスメソッド「X class>>#new:」を定義して、そこでセッター「X>>#a:」をコールしています。

Object subclass: #X
    instanceVariableNames: 'a b'
X >> a
    ^a
X >> a: val
    a := val
X >> / newB
    b := newB.
    Transcript cr; show: self.
    ^self
X >> < other
    Transcript space; show: other
X >> printString
    ^a a, 'スケッチ', b printString
X class >> initialize   "X initialize"
    Smalltalk at: #_ put: (self new: 'ひだまり')
X class >> / a
    ^self new: a
X class >> new: a
    ^self new a: a; yourself
X class >> printString
    ^'365'
X initialize
X / _ / X < #来週も見てくださいね!

ゆの in C#

Squeak Smalltalk では内部クラスは使えないのでクラス名は「Program」に。そのかわり、クラス変数は大文字からはじめるので x ではなく X を使用。

アンダーラインは全角「_」で逃げています。ただし「_」は大文字とは判断されず、コンパイル時に「Error: _ class variable name should be capitalized; proceed to include anyway.」と叱られます。でもこのエラーは無視でき、Proceed すれはそのままコンパイルは通ります。

メソッドの多重定義はできないので条件分岐でシミュレート。

Smalltalk には main() のような概念がないので、Main はクラスメソッド #example として定義。Program example で起動できます。もちろん「X / _ / X < 来週も見てくださいね!」をコードペイン内で選択し、ちょくせつ評価(do it)して動かすことも可能です。

Object subclass: #Program
    classVariableNames: 'X 来週も見てくださいね! _'
Program >> / other
    (other isKindOf: Integer) ifTrue: [
        Transcript cr;
            show: 'ひだまりスケッチ';
            show: self;
            show: other.
        ^self].
    (other isKindOf: Program) ifTrue: [^other]
Program >> < other
    Transcript show: other
Program >> printString
    ^'×'
Program >> initialize   "Program initialize"
    来週も見てくださいね! := ' 来週も見てくださいね!'.
    X := self new.
    _ := 365
Program class >> example   "Program example"
    X / _ / X < 来週も見てくださいね!

ゆの in Perl

Smalltalk には bless のようなしくみはないので、グローバル変数 X に代入した文字列 'ひだまり' について、インスタンス特異的クラスを作って代用しています。X を新しく設けたインスタンス特異的クラスに属させることは、本来であれば「X assureUniClass」でいけるはずなのですが、なぜか空文字列になってしまうので、「X become: (X as: X assureUniClass class)」とくどいことをしています。

X のインスタンス特異的クラスは文字列クラスのサブクラスになるのですが、あいにく文字列クラスの類にはインスタンス変数を作ることができないので、レシーバの文字数で #/ のコールが初回か否かを判断しています。

やはりアンダーバーは全角で逃げています。あしからず。

X := 'ひだまり'.
X become: (X as: X assureUniClass class).
X class compile: '/ other ^self, (self size = 4 ifTrue: [''スケッチ''] ifFalse: [''365''])'.
X class compile: '< other Transcript cr; show: self, '' '', other'.

X / _ / X < '来週も見てくださいね!'