RubyJS - JavaScript 实现的 Ruby
RubyJS 是一个用 JavaScript 实现了 Ruby 一些基本类的所有方法,例如 Array, String, Numbers, Time 等等。
Get ruby.js
Get the files at the RubyJS core-lib repository. And include the minified ruby.min.js file in your site.
<script src="/javascripts/ruby.min.js"></script> <script> var str = R("hello world"); alert(str.capitalize()); </script>
Try RubyJS in your browser
RubyJS is included on this page, so just open your JavaScript console.
With Rails
There's a Rails asset-pipeline gem for RubyJS.
# in Gemfile gem 'rubyjs-rails' # In your application.js manifest: //= require ruby
NPM Module
RubyJS can be installed as an npm module.
$ npm install rubyjs
Then simply require rubyjs which will add the R and RubyJS to the global object.
require('rubyjs'); R.puts("hello");
R(obj) method
R(obj) typecasts and returns its argument into a corresponding RubyJS object.
R(1) // => RubyJS.Fixnum R("foo") // => RubyJS.String R([1,15,8]) // => RubyJS.Array
Call any of the implemented RubyJS methods on the returned object.
R(1).even() // => false R(123.456).round(-1) // => 120 R("foo").capitalize() // => "Foo" R([1,15,8]).size() // => 3
Chainable
RubyJS methods return RubyJS object. So they are inherently chainable.
R(123.456).round(-1).even() // => true R("foo").capitalize().center(5) // => " Foo " R([1,15,8]).size().odd() // => true
Native objects
RubyJS classes are wrappers around Javascrip native objects or primitives. Access the underlying object with to_native().
R("title").capitalize().to_native() // 'Title' // to_native(true) recursively unboxes array R([1,2,R(3)]).to_native(true) // [1,2,3]
Recursive chaining
By default the members of an Array are not typecasted. You can do so by passing true to R( ) or new R.Array().
R([1] ).get(0).odd() // TypeError: Object 1 has no method 'odd' R([1], true).get(0).odd() // true new R.Array([1,2], true) // has the same effect
to_native(true) typecasts recursively to native JS objects
arr = R([1,2,3], true) arr.set(1, R(['foo']) arr.to_native(true) // => [1,['foo'],3]
Blocks and Iterators
Basics
RubyJS supports Ruby Enumerator. Blocks are handled with JavaScript functions.
R(['a', 'b']).each(function (w) { console.log(w) }) R(1).upto(5, function (i) { console.log(i) })
Symbol to Proc
R.proc(method_name)
provides the same functionality as Ruby Symbol#to_proc, just in a more JavaScript way of doing things. You can pass additional arguments to the method call.
R.w('foo bar').map(function (w) { return w.capitalize() }); R.w('foo bar').map(R.proc('capitalize')); R.w('foo bar').map(R.proc('ljust', 20));
Enumerator
Methods accepting a block return an Enumerator when not given a block to execute. Enumerator includes all the methods of the Enumerable mixin.
en = R(['a', 'b']).each() // RubyJS.Enumerator en.each_with_index(function (w,i) { console.log("#{w} #{i}") }) R(1).upto(5).to_a() // [1,2,3,4,5] (RubyJS.Array)
Block arguments not typecasted
Enumerable adapt to the arity of the block.
points = R([[1,-5], [2,4]]) points.each(function (arr) { // arr: [1, -5] // arr: [2, 4] }) points.each(function (x,y) { // x: 1, y: -5 // x: 2, y: 5 })
Chaining iterators
Enumerators also allow iterators to be chained. Although it is recommended for performance and clarity uses not to.
points = R(['cat', 'dog']) points.each_with_index().each(function (arr) { // arr: ['cat', 0] // arr: ['dog', 1] })
Ruby/JavaScript mapping
Constructors
An alternative to creating objects with R() is to call their constructors directly. Use JavaScript style constructors (new R.String() ) when you know the type for performance. The Ruby style (R.String.new) implements the behaviour of Ruby.
// ::new has the same behaviour as its ruby equivalent. R.String.new('foo') // Javascript style instantiation is optimized for speed. new R.String('foo')
Naming/Aliases
Ruby allows special characters in its method names. Following rules apply:
- Question marks are omitted. include?() -> include()
- Bang methods: capitalize!() -> capitalize_bang()
- +, -, ** have aliases, or can be called directly str['+'](other)