Ruby 風 mofmof.js
mofmof.js が String.prototype 等を拡張しているのは、Ruby などの OOP 言語の良さを取り込むためです。
mofmof.js に同梱されている es.js や ruby.js を追加すると
- Array#reject, select, flatten, map, each, or, and, fill, shuffle, assoc, index, uniq, collect, delete_at
- String#insert, remove, to_f, to_i, to_s, sub, gsub, scan, strip, upcase, downcase, swapcase, ljust, rjust, center
- Number#to_s, upto, downto, step
といった Ruby 由来のメソッドが利用可能になります。
mofmof.js では、PHP や Python といった他の言語の基本的な API を追加で取り込もうとしており、API セットを切り替えるための実装も予定されています。
Ruby のコードを JavaScript に変換する Opal
MOONGIFT さんの Rubyで書いてJavaScriptに変換「Opal」を拝見し、
ちょっと気になったので比較してみました。
左が Ruby (Opal)、右が mofmof.js で書いた Ruby 風のコード
5..times do |i| puts "#{i+1} time#{"s" if i>0}." end [1, 2, 3, 4].each do |a| puts a end class Foo attr_accessor :name end adam = Foo.new adam.name = 'Adam Beynon' puts adam.name
5..times(function(i) { mm.say( "@@ time@@.".at(i + 1, i ? "s" : "") ) }); [1, 2, 3, 4].each(function(a) { mm.say(a); }); adam = { set name(v) { this._n = v; }, get name() { return this._n; } }; adam.name = "Adam Beynon"; mm.say( adam.name );
左が Ruby (Opal)、右が Opal で生成した JavaScript のコード
5..times do |i| puts "#{i+1} time#{"s" if i>0}." end [1, 2, 3, 4].each do |a| puts a end class Foo attr_accessor :name end adam = Foo.new adam.name = 'Adam Beynon' puts adam.name
(function() { var __opal = Opal, self = __opal.top, __scope = __opal, nil = __opal.nil, __breaker = __opal.breaker, __slice = __opal.slice, __range = __opal.range, __klass = __opal.klass; var adam = nil, __a, __b, __c; __range(5, (__b = self, __b.$times._p = (__a = function(i) { var __a, __b; if (i == null) i = nil; return this.$puts("" + ((__a = i, __b = 1, typeof(__a) === 'number' ? __a + __b : __a['$+'](__b))) + " time" + ((function() { if (i['$>'](0)) { return "s" } else { return nil }; return nil; }).call(this)) + ".") }, __a._s = self, __a), __b.$times()), false); (__c = [1, 2, 3, 4], __c.$each._p = (__a = function(a) { if (a == null) a = nil; return this.$puts(a) }, __a._s = self, __a), __c.$each()); (function(__base, __super){ function Foo() {}; Foo = __klass(__base, __super, "Foo", Foo); var Foo_prototype = Foo.prototype, __scope = Foo._scope; Foo_prototype.name = nil; return Foo_prototype.$name = function() { return this.name }, Foo_prototype['$name='] = function(val) { return this.name = val }, nil })(self, null); adam = __scope.Foo.$new(); adam['$name=']("Adam Beynon"); return self.$puts(adam.$name()); })();
mofmof.js も、現時点でかなり Ruby 風味なコードは書けるのですが、
まだまだ先は長そうですね。