scala e jruby
Post on 02-Dec-2014
47 Views
Preview:
DESCRIPTION
TRANSCRIPT
Scala e JRubyUnião de dois mundos
Maurício Eduardo Chicupo Szabohttp://about.me/mauricio.szabo
Scala World
SQL é bom!
Paralelismo, actors…
Linguagens devem ser estáticas!
Why?
Ruby World
ORMs são bons!
Fibers, workers, redis...
Linguagens dinâmicas são melhores!
Why?
Because We CAN!
How?
● Ruby roda na JVM - JRuby.
● Sintaxes semelhantes
Sintaxes
numbers = (1..20).map { |e| e * 2 }h = numbers.each_with_index .inject({}) do |hash, (number, index)| hash.merge(index => number)end
val numbers = 1 to 20 map { e => e * 2 }val m = numbers.zipWithIndex .foldLeft(Map[Int, Int]()) { case(map, (number, index)) => map + (index -> number)}
But HOW?
● org.jruby.Ruby ← Environment
● Ruby#evalScriptlet
● IRubyObject
● IRubyObject#callMethod
Ruby("puts 'Hello, world!'")
Scala Way
● AbstractRubyWrapper
● trait Ruby[A <: AbstractRubyWrapper]
● __toRubyWrapper
val r = Ruby("'some string'")r: RubyImpl = "some string"
r.upcaseres0: RubyImpl = "SOME STRING"
Scala Way
● init
● normalize ← params enviados para JRuby
val bd = Ruby(‘"BigDecimal").init("2.05")bd: ruby.RubyImpl = #<BigDecimal:58b0dd88,'0.205E1',3(4)>
(bd + 20).to_fres0: ruby.RubyImpl = 22.05
Scala Conversions
● Estático → Dinâmico → Estático → Dinâmico
● null → nil (NilClass) → ……..?
(bd + Ruby("20")).to_fres0: ruby.RubyImpl = 22.05
Estático / Dinâmico
● Conversões de dinâmico para estático
● rubyResult.as(String)
● rubyResult.any
val m = Ruby("{:ten => 10, :twenty => 20}").as(Map)m: Map[Any,Any] = Map('twenty -> 20, 'ten -> 10)
val d = Ruby("10").as(Int)d: Int = 10
Scala Conversions
● Objects → Boolean
if(Ruby("nil")) 10 else 20res0: Int = 20
if(Ruby("10")) 10 else 20res1: Int = 10
if(Ruby("0")) 10 else 20res2: Int = 10
Scala Conversions
● Funções → Proc → Funções
val h = Ruby("Hash").init { (_: Any, e: String) => e.toUpperCase }h: ruby.RubyImpl = {}
h("Some String")res0: ruby.RubyImpl = "SOME STRING"
h(10)java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
● Ruby nil é uma classe, Scala null é… bem…
● val a: String = null
● rubyObject.as[String] // => Option[String]
Nulo...
val s = Ruby("'Hello, world!'").as[String]s: Option[String] = Some(Hello, world!)
val s = Ruby("nil").as[String]s: Option[String] = None
● Cast de Listas
● Cast de Mapas
Casts de Generics
val list = Ruby("[1, 2, 3]").as[List, Int]list: Option[List[Int]] = Some(Vector(1, 2, 3))
val map = Ruby("{:ten => 10}").asMap[Symbol, Int]map: Option[Map[Symbol,Int]] = Some(Map('ten -> 10))
val vector = Ruby("[1, 2, 3]").as[Vector, Int]vector: Option[Vector[Int]] = Some(Vector(1, 2, 3))
Subclassing
● SimpleSubclass
● Override
● (alguns problemas com classe… ainda)
class Skate extends SimpleSubclass("Vehicles"){ def max_speed = 45}
ActiveRecord
● activerecord.Model
object Person extends active_record.Model { scope('foo, this.where('name -> "Foo")) scope('age, a => this.where('age -> a))
this has_many 'children}
Person.where('name -> "Foo").where('age ->)Person.foo.age(17).limit(20)
Sinatra
● Not there yet...
class SinatraApp extends SubclassOf(SinatraApp)
object SinatraApp extends Subclass[SinatraApp]("Sinatra::Base") {
this.reset_!
this.get("/", { () => "Hello, world!" })}
But...
WHY????
Mais informações
https://github.com/mauricioszabo/Ruby2Scala
http://jruby.org/apidocs/
top related