SlideShare a Scribd company logo
1 of 36
Download to read offline
Ruby
Play
2.0
       X    On
           Rails

               by @danicuki
Documentation
http://www.playframework.com/documentation/   http://guides.rubyonrails.org/
Installing

$   apt-get install java         $	
  apt-­‐get	
  install	
  ruby
$   wget play-2.1.0.zip          $	
  apt-­‐get	
  install	
  rubygems
$   unzip play-2.1.0.zip         $	
  gem	
  install	
  rails
$   export
    PATH=$PATH:/pathToPlay



http://www.playframework.com/
documentation/2.1.0/Installing
First App


$ play new myapp     $	
  rails	
  new	
  myapp
Project Structure
app/                      app/
 ! assets                  ! assets
     ! stylesheets             ! stylesheets
     ! javascripts             ! javascripts
 ! controllers             ! controllers
 ! models                  ! helpers
 ! views                   ! mailers
conf/                      ! models
 ! application.conf        ! views
 ! routes                 config/
public/                    ! application.rb
project                    ! routes.rb
 ! build.properties        ! database.yml
 ! Build.scala            config.ru
 ! plugins.sbt            db
lib/                      GemFile
logs/                     lib/
target/                   log/
                          public/
 ! scala-2.10.0           script/
test/                     test/
                          tmp/
                          vendor/
Console
Dependencies
Maven
project/Build.scala
val appDependencies = Seq(
  "postgresql" % "postgresql" % "8.4-702.jdbc4"
  "org.mockito" % "mockito-all" % "1.8.5" % "test"
)

RubyGems
Gemfile
gem "mysql2"
group :test do
  gem "webmock"
end
Dependencies Support
       429.000 jars
     mvnrepository.com




       52,468 gems
      rubygems.org
Views Templates
STE    (Scala Template Engine)

@(title: String)(content: Html)
<title>
  @Messages("site.title") - @title
</title>
@{(video  "title")(0).text}


ERB      (Embedded Ruby)

<title>
	
  	
  <%=	
  t("site.title")	
  %>	
  -­‐	
  <%=	
  yield(:title)	
  %>
</title>
<%=	
  video['title']	
  %>
js / css
<link rel="stylesheet" href="@routes.Assets.at("stylesheets/grid.css")">
<link rel="stylesheet" href="@routes.Assets.at("stylesheets/style.css")">
<link rel="stylesheet" href="@routes.Assets.at("stylesheets/galleriffic.css")">
<script src="@routes.Assets.at("javascripts/applicaton.js")" type="text/javascript" />
<script src="@routes.Assets.at("javascripts/jquery.js")" type="text/javascript" />




 <%=	
  javascript_include_tag	
  :all,	
  :cache	
  =>	
  true	
  %>	
  
 <%=	
  stylesheet_link_tag	
  :all,	
  :cache	
  =>	
  true	
  %>
Links
<li class="menu">
  <a href="@routes.Application.cantora">@Messages("site.singer")</a>
</li>




 <li	
  class="menu">
 	
  	
  <%=	
  link_to	
  "#{t('site.singer')}",	
  {:controller	
  =>	
  "cantora"}	
  %>
 </li>
Routes
GET     /cantora         controllers.Application.cantora
GET     /musicas         controllers.Application.music
GET     /agenda          controllers.Application.shows
GET     /novidades       controllers.Application.news

GET   /clients/:id         controllers.Clients.show(id: Long)




map.connect	
  ':controller/:action/:id'
Controllers
def   cantora = Action { implicit request =>; Ok(views.html.cantora()) }
def   music = Action { implicit request =>; Ok(views.html.music()) }
def   shows = Action { implicit request => Ok(views.html.shows()) }
def   news = Action { implicit request => Ok(views.html.news()) }

/app/views/[method_name].scala.html



class	
  CantoraController	
  <	
  ApplicationController
        def	
  index
	
  	
  end
end
class	
  NewsController	
  <	
  ApplicationController
	
   def	
  index
	
   end
end
/app/views/[controller_name]/index.erb.html
Databases
conf/application.conf:

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/playdb"
db.default.user=playdbuser
db.default.pass="a strong password"




config/database.yml:

development:
	
  	
  adapter:	
  mysql2
	
  	
  database:	
  blog_development
	
  	
  username:	
  root
	
  	
  password:
SQL API:                          Databases
val countries = SQL("Select name,population from Country")().collect {
  case Row("France", _) => France()
  case Row(name:String, pop:Int) if(pop > 1000000) => BigCountry(name)
  case Row(name:String, _) => SmallCountry(name)
}

val result: Int =
  SQL("delete from City where id = {id}").on(“id” -> 99).executeUpdate()

Active	
  Record:

Country.all.map	
  do	
  |c|
	
  	
  if	
  (c.name	
  ==	
  “France”)
	
  	
  	
  	
  France.new
	
  	
  else	
  if	
  (c.pop	
  >	
  1000000)    Country.delete(99)
	
  	
  	
  	
  BigCountry.new(c.name)
	
  	
  else
	
  	
  	
  	
  SmallCountry.new(c.name)
	
  	
  end
end
Databases
                                                OGH
                              (Old Good Hibernate)


Active	
  Record:

Country.all.map	
  do	
  |c|
	
  	
  if	
  (c.name	
  ==	
  “France”)
	
  	
  	
  	
  France.new
	
  	
  else	
  if	
  (c.pop	
  >	
  1000000)         Country.delete(99)
	
  	
  	
  	
  BigCountry.new(c.name)
	
  	
  else
	
  	
  	
  	
  SmallCountry.new(c.name)
	
  	
  end
end
Migrations / Evolutions
# --- !Ups
CREATE TABLE Users (
    id bigint(20) NOT NULL AUTO_INCREMENT,
    email varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    PRIMARY KEY (id)
);

# --- !Downs                                                               run: AUTOMATIC!
DROP TABLE Users;                                  conf/evolutions/{database name}/{#}.sql


class	
  CreateUsers	
  <	
  ActiveRecord::Migration
	
  	
  def	
  up
	
  	
  	
  	
  create_table	
  :users	
  do	
  |t|
	
  	
  	
  	
  	
  	
  t.string	
  :email
	
  	
  	
  	
  	
  	
  t.string	
  :password
	
  	
  	
  	
  	
  	
  t.timestamps
	
  	
  	
  	
  end
	
  	
  end
	
  	
  def	
  down
	
  	
  	
  	
  drop_table	
  :users                                  run:	
  rake	
  db:migrate
	
  	
  end                                         db/migrate/{timestamp}_create_users.rb
end
Web Services
def videos = Action { implicit request =>
  Async {
    val uri = "http://gdata.youtube.com/feed.xml"
    WS.url(uri).get().map { response =>
      Ok(views.html.videos(response.xml  "entry"))
    }
  }
}



class	
  VideosController	
  <	
  ApplicationController
	
  	
  def	
  index
	
  	
  	
  	
  uri	
  =	
  "http://gdata.youtube.com/feed.xml"
	
  	
  	
  	
  video_feed	
  =	
  RestClient.get(uri)
	
  	
  	
  	
  @videos	
  =	
  Hash.from_xml(video_feed)['feed']['entry']
	
  	
  end
end
XML
Ok(views.html.videos(response.xml  "entry"))

@(videos: scala.xml.NodeSeq)

@videos.map { video =>
    <a href="@{ ((video  "group")  "player")(0).attribute("url")}">
       @{(video  "title")(0).text}
    </a>
}


@videos	
  =	
  Hash.from_xml(video_feed)['feed']['entry']

<%	
  @videos.each	
  do	
  |video|	
  %>
	
  	
  	
  	
  	
  <a	
  href="<%=	
  video['group']['player']['url']	
  %>">
	
  	
  	
  	
  	
  	
  	
  	
  	
  <%=	
  video['title']	
  %>
	
  	
  	
  	
  	
  </a>
<%	
  end	
  %>
WS.url("https://graph.facebook.com/daniella.alcarpe/albums").get().map	
  {	
  response	
  =>
	
  	
  	
  	
  val	
  albuns	
  =	
  (response.json	
  	
  "data").
	
  	
  	
  	
  	
  	
  as[List[JsObject]].filter(album	
  =>
	
  	
  	
  	
  	
  	
  	
  	
  (album	
  	
  "description").toString.equals(""*""))
	
  
	
  	
  	
  	
  val	
  photos	
  =	
  albuns.map	
  {	
  album	
  =>
	
  	
  	
  	
  	
  	
  WS.url("https://graph.facebook.com/"	
  +	
  (album	
  	
  "id").toString.replace(""",	
  "")	
  +	
  
"/photos").get().map	
  {	
  response2	
  =>
	
  	
  	
  	
  	
  	
  	
  	
  (response2.json	
  	
  "data").as[List[JsObject]].map	
  {	
  photo	
  =>
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ((photo	
  	
  "images")(3)	
  	
  "source").toString.replace(""",	
  "")
	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  }
	
  	
  Ok(views.html.photos(photos))


                                                                                                         JSON
}


@albuns_photos	
  =	
  {}
	
  	
  	
  	
  @albuns	
  =	
  []
	
  	
  	
  	
  albuns	
  =	
  JSON.parse(RestClient.get("https://graph.facebook.com/
daniella.alcarpe/albums"))["data"]
	
  	
  	
  	
  albuns.each	
  do	
  |album|
	
  	
  	
  	
  	
  	
  if	
  (album['description']	
  ==	
  "*")
	
  	
  	
  	
  	
  	
  	
  	
  photos	
  =	
  JSON.parse(RestClient.get("https://graph.facebook.com/
#{album['id']}/photos"))["data"]
	
  	
  	
  	
  	
  	
  	
  	
  albuns_photos	
  =	
  photos.map	
  {|p|	
  p["images"][3]["source"]}
	
  	
  	
  	
  	
  	
  	
  	
  album['photos']	
  =	
  albuns_photos
	
  	
  	
  	
  	
  	
  	
  	
  @albuns	
  <<	
  album
	
  	
  	
  	
  	
  	
  end
	
  	
  	
  	
  end
Cache
def videos = Cached("videos", 18000) {
  Action {
  ...
  }
}




class	
  VideosController	
  <	
  ApplicationController
	
  	
  	
  	
  caches_action	
  :index,	
  :expires_in	
  =>	
  1.day
end
Unit Tests
@Test def myTest() {
  val array = List(1, 2, 3)
  assert(array(0) === 1)
}




test	
  "my	
  test"	
  do
	
  	
  array	
  =	
  [1,	
  2,	
  3]
	
  	
  assert_equal	
  1,	
  array.first
end
Specs
class HelloWorldSpec extends Specification {
  "The 'Hello world' string" should {
    "contain 11 characters" in {
                                                                   specs2
      "Hello world" must have size(11)
    }
    "end with 'world'" in {
      "Hello world" must endWith("world")
                                                                   autotest:
  }
    }
                                                                   $ ~ test
}



describe	
  "HelloWorldSpec"	
  do
  context	
  "The	
  'Hello	
  world'	
  string	
  should"	
  do
  	
  	
  it	
  "contain 11 characters"	
  do                      rspec
  	
  	
  	
  	
  "Hello	
  world".size.should	
  eq(11)
  	
  	
  end
  	
  	
  it	
  "end with 'world'"	
  do
  	
  	
  	
  	
  "Hello	
  world".should	
  end_with("world")     $ autospec
  	
  	
  end
  end
end
In Procfile:
                                 Deploy
web: target/start -Dhttp.port=${PORT} -DapplyEvolutions.default=true -
Ddb.default.url=${DATABASE_URL} -Ddb.default.driver=org.postgresql.Driver

In project/Build.scala:
val appDependencies = Seq(
  "postgresql" % "postgresql" % "8.4-702.jdbc4"
)

$ heroku create
$ git push heroku master




$	
  heroku	
  create
$	
  git	
  push	
  heroku	
  master
Adendo




Scala    X       Ruby


                    by @danicuki
Lambda

list.filter(_ < 100)      list.select	
  do	
  |el|
                          	
  	
  el	
  <	
  100
list.filter {             end	
  
  el: Int => (el < 100)
}
Types

Static:                  Dynamic:

val a = new              a	
  =	
  Hash.new
  HashMap[Int, String]   a	
  =	
  “BOO!”
Pattern Matching
                             require	
  'case'
                             def	
  matchTest	
  x
                             	
  case	
  x
                             	
  when	
  7
def myMatch(x: Any): Any =   	
  	
  	
  "seven"
x match {                    	
  when	
  "string"
  case 7 => “seven”
                             	
  	
  	
  0
  case “string” => 0
                             	
  when	
  Case::All[Integer]
  case y:Int => “no.”
  case 2 :: tail => tail     	
  	
  	
  "no."
}                            	
  when	
  
                             Case::Array[2,Case::Any]
                             	
  	
  	
  x[1..-­‐1]
                             	
  end
                             end
Monkey Patch
class MySuperString(original: String) {
  def myMethod = "yess!!!"
}
implicit def string2super(x: String) =
  new MySuperString(x)

println("a".myMethod) // => yess!!!


class	
  String
	
  	
  def	
  my_method
	
  	
  	
  "yess!!!"
	
  	
  end
end

puts	
  "a".my_method	
  #	
  =>	
  yess!!!
Dynamic Calls
 class Animal extends Dynamic                {
   def _select_(name: String)                = println("Animal says " + name)
   def _invoke_(name: String,                args: Any*) = {
     println("Animal wants to                " + name + args.mkString(", "))
     this
   }            val animal =        new Animal
 }              animal.qualk        // => Animal says qualk
                       animal.say("hello") // => Animal wants to say hello
class	
  Animal
	
  	
  def	
  method_missing	
  name,	
  *args
	
  	
  	
  	
  if	
  args.empty?
	
  	
  	
  	
  	
  	
  puts	
  "Animal	
  says	
  "	
  +	
  name.to_s
	
  	
  	
  	
  else
	
  	
  	
  	
  	
  	
  puts	
  "Animal	
  wants	
  to	
  "	
  +	
  name.to_s	
  +	
  	
  args.join(",	
  ")
	
  	
  	
  	
  end
	
  	
  	
  	
  self               animal	
  =	
  Animal.new
	
  	
  end                        animal.qualk	
  #	
  =>	
  Animal	
  says	
  :	
  qualks	
  !
end                                animal.say("hello")	
  #	
  =>	
  Animal	
  wants	
  to	
  say	
  hello
Modules / Traits
trait PimpMyClass {
  def myMethod = println("myMethod")
}
class IncludeTrait extends PimpMyClass
(new IncludeTrait).myMethod


module	
  PimpMyClass
	
  	
  def	
  my_method
	
  	
  	
  	
  puts	
  "my_method"
	
  	
  end
end
class	
  IncludeModule
	
  	
  include	
  PimpMyClass
end
IncludeModule.new.my_method
Duck Typing
class     Duck {                 def ActAsADuck(a: { def quack; def walk })= {
  def     quack = ...                 a.quack
  def     walk = ...                  a.walk
                                 }
}
class     Platypus {             val duck = new Duck
  def     quack = ...            val platypus = new Platypus
  def     walk = ...             ActAsADuck(duck)
}                                ActAsADuck(platypus)

class	
  Duck                    def	
  act_as_a_duck	
  animal
	
  	
  def	
  quack;	
  end     	
  	
  animal.quack
	
  	
  def	
  walk;	
  end      	
  	
  animal.walk
end                              end

class	
  Platypus                duck	
  =	
  Duck.new
	
  	
  def	
  quack;	
  end     platypus	
  =	
  Platypus.new
	
  	
  def	
  walk;	
  end      act_as_a_duck(duck)
end                              act_as_a_duck(platypus)
Actors
Performance
                                80
               70.74
                                                     Scala
                            60                       JRuby
                                                     Ruby


       39.74               40



                       20


2.07
                       0

                                     Source : http://shootout.alioth.debian.org
References
✦ http://www.playframework.com/documentation
✦ http://guides.rubyonrails.org/
✦ http://www.agileandart.com/
✦ http://www.slideshare.net/El_Picador/scala-vs-ruby
Obrigado!
www.agileandart.com
    @danicuki

More Related Content

What's hot

Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveepamspb
 
Java Play Restful JPA
Java Play Restful JPAJava Play Restful JPA
Java Play Restful JPAFaren faren
 
Java Play RESTful ebean
Java Play RESTful ebeanJava Play RESTful ebean
Java Play RESTful ebeanFaren faren
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio Martín
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Roy Yu
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node jsfakedarren
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
Migrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsMigrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsSteven Evatt
 
JavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and EcosystemJavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and EcosystemAlexander Casall
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to CeleryIdan Gazit
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Eric Palakovich Carr
 
Effective Doctrine2: Performance Tips for Symfony2 Developers
Effective Doctrine2: Performance Tips for Symfony2 DevelopersEffective Doctrine2: Performance Tips for Symfony2 Developers
Effective Doctrine2: Performance Tips for Symfony2 DevelopersMarcin Chwedziak
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queueAlex Eftimie
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryMauro Rocco
 

What's hot (20)

Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
Java Play Restful JPA
Java Play Restful JPAJava Play Restful JPA
Java Play Restful JPA
 
Java Play RESTful ebean
Java Play RESTful ebeanJava Play RESTful ebean
Java Play RESTful ebean
 
Rails Security
Rails SecurityRails Security
Rails Security
 
Ant
AntAnt
Ant
 
Introduction to Flask Micro Framework
Introduction to Flask Micro FrameworkIntroduction to Flask Micro Framework
Introduction to Flask Micro Framework
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
Presentation
PresentationPresentation
Presentation
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Migrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain PointsMigrating PriceChirp to Rails 3.0: The Pain Points
Migrating PriceChirp to Rails 3.0: The Pain Points
 
JavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and EcosystemJavaOne - The JavaFX Community and Ecosystem
JavaOne - The JavaFX Community and Ecosystem
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
 
Debugging on rails
Debugging on railsDebugging on rails
Debugging on rails
 
Intro to-ant
Intro to-antIntro to-ant
Intro to-ant
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
Effective Doctrine2: Performance Tips for Symfony2 Developers
Effective Doctrine2: Performance Tips for Symfony2 DevelopersEffective Doctrine2: Performance Tips for Symfony2 Developers
Effective Doctrine2: Performance Tips for Symfony2 Developers
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queue
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
 

Similar to Play vs Rails

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebFabio Akita
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesLindsay Holmwood
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortalJennifer Bourey
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascriptaglemann
 
Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Ngoc Dao
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsMykyta Protsenko
 
Express Presentation
Express PresentationExpress Presentation
Express Presentationaaronheckmann
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 

Similar to Play vs Rails (20)

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações Web
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascript
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 
Play framework
Play frameworkPlay framework
Play framework
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and Ops
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 

More from Daniel Cukier

Solidity: Zero to Hero Corporate Training
Solidity: Zero to Hero Corporate TrainingSolidity: Zero to Hero Corporate Training
Solidity: Zero to Hero Corporate TrainingDaniel Cukier
 
Spring e Injeção de Dependência
Spring e Injeção de DependênciaSpring e Injeção de Dependência
Spring e Injeção de DependênciaDaniel Cukier
 
Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...
Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...
Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...Daniel Cukier
 
Startup Communities: From Nascence to Maturity
Startup Communities: From Nascence to MaturityStartup Communities: From Nascence to Maturity
Startup Communities: From Nascence to MaturityDaniel Cukier
 
Technology Startups Ecosystem in China - Lessons to other ecosystems
Technology Startups  Ecosystem in China - Lessons to other ecosystemsTechnology Startups  Ecosystem in China - Lessons to other ecosystems
Technology Startups Ecosystem in China - Lessons to other ecosystemsDaniel Cukier
 
Software Startup Ecosystems Evolution - The New York City Case Study
Software Startup Ecosystems Evolution - The New York City Case StudySoftware Startup Ecosystems Evolution - The New York City Case Study
Software Startup Ecosystems Evolution - The New York City Case StudyDaniel Cukier
 
Maturity model for Startup Ecosystems
Maturity model for Startup EcosystemsMaturity model for Startup Ecosystems
Maturity model for Startup EcosystemsDaniel Cukier
 
Why Google Cloud is so special? Stories from a cloud user
Why Google Cloud is so special?  Stories from a cloud userWhy Google Cloud is so special?  Stories from a cloud user
Why Google Cloud is so special? Stories from a cloud userDaniel Cukier
 
Software Architectures for a Single Person Team
Software Architectures for a Single Person TeamSoftware Architectures for a Single Person Team
Software Architectures for a Single Person TeamDaniel Cukier
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaDaniel Cukier
 
O dia a dia de uma Startup
O dia a dia de uma StartupO dia a dia de uma Startup
O dia a dia de uma StartupDaniel Cukier
 
Injeção de Dependência e Testes com Dublês
Injeção de Dependência e Testes com DublêsInjeção de Dependência e Testes com Dublês
Injeção de Dependência e Testes com DublêsDaniel Cukier
 
Selecting Empirical Methods for Software Engineering
Selecting Empirical Methods for Software EngineeringSelecting Empirical Methods for Software Engineering
Selecting Empirical Methods for Software EngineeringDaniel Cukier
 
Is Computer Science Science?
Is Computer Science Science?Is Computer Science Science?
Is Computer Science Science?Daniel Cukier
 
Better Science Through Art
Better Science Through ArtBetter Science Through Art
Better Science Through ArtDaniel Cukier
 
Designed as Designer
Designed as DesignerDesigned as Designer
Designed as DesignerDaniel Cukier
 
When Should You Consider Meta Architectures
When Should You Consider Meta ArchitecturesWhen Should You Consider Meta Architectures
When Should You Consider Meta ArchitecturesDaniel Cukier
 

More from Daniel Cukier (20)

Solidity: Zero to Hero Corporate Training
Solidity: Zero to Hero Corporate TrainingSolidity: Zero to Hero Corporate Training
Solidity: Zero to Hero Corporate Training
 
Spring e Injeção de Dependência
Spring e Injeção de DependênciaSpring e Injeção de Dependência
Spring e Injeção de Dependência
 
Pair programming
Pair programmingPair programming
Pair programming
 
Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...
Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...
Eficiency and Low Cost: Pro Tips for you to save 50% of your money with Googl...
 
Startup Communities: From Nascence to Maturity
Startup Communities: From Nascence to MaturityStartup Communities: From Nascence to Maturity
Startup Communities: From Nascence to Maturity
 
Technology Startups Ecosystem in China - Lessons to other ecosystems
Technology Startups  Ecosystem in China - Lessons to other ecosystemsTechnology Startups  Ecosystem in China - Lessons to other ecosystems
Technology Startups Ecosystem in China - Lessons to other ecosystems
 
Software Startup Ecosystems Evolution - The New York City Case Study
Software Startup Ecosystems Evolution - The New York City Case StudySoftware Startup Ecosystems Evolution - The New York City Case Study
Software Startup Ecosystems Evolution - The New York City Case Study
 
Maturity model for Startup Ecosystems
Maturity model for Startup EcosystemsMaturity model for Startup Ecosystems
Maturity model for Startup Ecosystems
 
Why Google Cloud is so special? Stories from a cloud user
Why Google Cloud is so special?  Stories from a cloud userWhy Google Cloud is so special?  Stories from a cloud user
Why Google Cloud is so special? Stories from a cloud user
 
Software Architectures for a Single Person Team
Software Architectures for a Single Person TeamSoftware Architectures for a Single Person Team
Software Architectures for a Single Person Team
 
Startup Communities
Startup CommunitiesStartup Communities
Startup Communities
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 
O dia a dia de uma Startup
O dia a dia de uma StartupO dia a dia de uma Startup
O dia a dia de uma Startup
 
Injeção de Dependência e Testes com Dublês
Injeção de Dependência e Testes com DublêsInjeção de Dependência e Testes com Dublês
Injeção de Dependência e Testes com Dublês
 
Selecting Empirical Methods for Software Engineering
Selecting Empirical Methods for Software EngineeringSelecting Empirical Methods for Software Engineering
Selecting Empirical Methods for Software Engineering
 
Is Computer Science Science?
Is Computer Science Science?Is Computer Science Science?
Is Computer Science Science?
 
Ruby Robots
Ruby RobotsRuby Robots
Ruby Robots
 
Better Science Through Art
Better Science Through ArtBetter Science Through Art
Better Science Through Art
 
Designed as Designer
Designed as DesignerDesigned as Designer
Designed as Designer
 
When Should You Consider Meta Architectures
When Should You Consider Meta ArchitecturesWhen Should You Consider Meta Architectures
When Should You Consider Meta Architectures
 

Recently uploaded

The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...amber724300
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...itnewsafrica
 

Recently uploaded (20)

The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
 

Play vs Rails

  • 1. Ruby Play 2.0 X On Rails by @danicuki
  • 3. Installing $ apt-get install java $  apt-­‐get  install  ruby $ wget play-2.1.0.zip $  apt-­‐get  install  rubygems $ unzip play-2.1.0.zip $  gem  install  rails $ export PATH=$PATH:/pathToPlay http://www.playframework.com/ documentation/2.1.0/Installing
  • 4. First App $ play new myapp $  rails  new  myapp
  • 5. Project Structure app/ app/ ! assets ! assets ! stylesheets ! stylesheets ! javascripts ! javascripts ! controllers ! controllers ! models ! helpers ! views ! mailers conf/ ! models ! application.conf ! views ! routes config/ public/ ! application.rb project ! routes.rb ! build.properties ! database.yml ! Build.scala config.ru ! plugins.sbt db lib/ GemFile logs/ lib/ target/ log/ public/ ! scala-2.10.0 script/ test/ test/ tmp/ vendor/
  • 7. Dependencies Maven project/Build.scala val appDependencies = Seq( "postgresql" % "postgresql" % "8.4-702.jdbc4" "org.mockito" % "mockito-all" % "1.8.5" % "test" ) RubyGems Gemfile gem "mysql2" group :test do gem "webmock" end
  • 8. Dependencies Support 429.000 jars mvnrepository.com 52,468 gems rubygems.org
  • 9. Views Templates STE (Scala Template Engine) @(title: String)(content: Html) <title> @Messages("site.title") - @title </title> @{(video "title")(0).text} ERB (Embedded Ruby) <title>    <%=  t("site.title")  %>  -­‐  <%=  yield(:title)  %> </title> <%=  video['title']  %>
  • 10. js / css <link rel="stylesheet" href="@routes.Assets.at("stylesheets/grid.css")"> <link rel="stylesheet" href="@routes.Assets.at("stylesheets/style.css")"> <link rel="stylesheet" href="@routes.Assets.at("stylesheets/galleriffic.css")"> <script src="@routes.Assets.at("javascripts/applicaton.js")" type="text/javascript" /> <script src="@routes.Assets.at("javascripts/jquery.js")" type="text/javascript" /> <%=  javascript_include_tag  :all,  :cache  =>  true  %>   <%=  stylesheet_link_tag  :all,  :cache  =>  true  %>
  • 11. Links <li class="menu"> <a href="@routes.Application.cantora">@Messages("site.singer")</a> </li> <li  class="menu">    <%=  link_to  "#{t('site.singer')}",  {:controller  =>  "cantora"}  %> </li>
  • 12. Routes GET /cantora controllers.Application.cantora GET /musicas controllers.Application.music GET /agenda controllers.Application.shows GET /novidades controllers.Application.news GET /clients/:id controllers.Clients.show(id: Long) map.connect  ':controller/:action/:id'
  • 13. Controllers def cantora = Action { implicit request =>; Ok(views.html.cantora()) } def music = Action { implicit request =>; Ok(views.html.music()) } def shows = Action { implicit request => Ok(views.html.shows()) } def news = Action { implicit request => Ok(views.html.news()) } /app/views/[method_name].scala.html class  CantoraController  <  ApplicationController def  index    end end class  NewsController  <  ApplicationController   def  index   end end /app/views/[controller_name]/index.erb.html
  • 15. SQL API: Databases val countries = SQL("Select name,population from Country")().collect { case Row("France", _) => France() case Row(name:String, pop:Int) if(pop > 1000000) => BigCountry(name) case Row(name:String, _) => SmallCountry(name) } val result: Int = SQL("delete from City where id = {id}").on(“id” -> 99).executeUpdate() Active  Record: Country.all.map  do  |c|    if  (c.name  ==  “France”)        France.new    else  if  (c.pop  >  1000000) Country.delete(99)        BigCountry.new(c.name)    else        SmallCountry.new(c.name)    end end
  • 16. Databases OGH (Old Good Hibernate) Active  Record: Country.all.map  do  |c|    if  (c.name  ==  “France”)        France.new    else  if  (c.pop  >  1000000) Country.delete(99)        BigCountry.new(c.name)    else        SmallCountry.new(c.name)    end end
  • 17. Migrations / Evolutions # --- !Ups CREATE TABLE Users ( id bigint(20) NOT NULL AUTO_INCREMENT, email varchar(255) NOT NULL, password varchar(255) NOT NULL, PRIMARY KEY (id) ); # --- !Downs run: AUTOMATIC! DROP TABLE Users; conf/evolutions/{database name}/{#}.sql class  CreateUsers  <  ActiveRecord::Migration    def  up        create_table  :users  do  |t|            t.string  :email            t.string  :password            t.timestamps        end    end    def  down        drop_table  :users run:  rake  db:migrate    end db/migrate/{timestamp}_create_users.rb end
  • 18. Web Services def videos = Action { implicit request => Async { val uri = "http://gdata.youtube.com/feed.xml" WS.url(uri).get().map { response => Ok(views.html.videos(response.xml "entry")) } } } class  VideosController  <  ApplicationController    def  index        uri  =  "http://gdata.youtube.com/feed.xml"        video_feed  =  RestClient.get(uri)        @videos  =  Hash.from_xml(video_feed)['feed']['entry']    end end
  • 19. XML Ok(views.html.videos(response.xml "entry")) @(videos: scala.xml.NodeSeq) @videos.map { video =>     <a href="@{ ((video "group") "player")(0).attribute("url")}">        @{(video "title")(0).text}     </a> } @videos  =  Hash.from_xml(video_feed)['feed']['entry'] <%  @videos.each  do  |video|  %>          <a  href="<%=  video['group']['player']['url']  %>">                  <%=  video['title']  %>          </a> <%  end  %>
  • 20. WS.url("https://graph.facebook.com/daniella.alcarpe/albums").get().map  {  response  =>        val  albuns  =  (response.json    "data").            as[List[JsObject]].filter(album  =>                (album    "description").toString.equals(""*""))          val  photos  =  albuns.map  {  album  =>            WS.url("https://graph.facebook.com/"  +  (album    "id").toString.replace(""",  "")  +   "/photos").get().map  {  response2  =>                (response2.json    "data").as[List[JsObject]].map  {  photo  =>                    ((photo    "images")(3)    "source").toString.replace(""",  "")                }            }        }    Ok(views.html.photos(photos)) JSON } @albuns_photos  =  {}        @albuns  =  []        albuns  =  JSON.parse(RestClient.get("https://graph.facebook.com/ daniella.alcarpe/albums"))["data"]        albuns.each  do  |album|            if  (album['description']  ==  "*")                photos  =  JSON.parse(RestClient.get("https://graph.facebook.com/ #{album['id']}/photos"))["data"]                albuns_photos  =  photos.map  {|p|  p["images"][3]["source"]}                album['photos']  =  albuns_photos                @albuns  <<  album            end        end
  • 21. Cache def videos = Cached("videos", 18000) {   Action { ...   } } class  VideosController  <  ApplicationController        caches_action  :index,  :expires_in  =>  1.day end
  • 22. Unit Tests @Test def myTest() { val array = List(1, 2, 3) assert(array(0) === 1) } test  "my  test"  do    array  =  [1,  2,  3]    assert_equal  1,  array.first end
  • 23. Specs class HelloWorldSpec extends Specification { "The 'Hello world' string" should { "contain 11 characters" in { specs2 "Hello world" must have size(11) } "end with 'world'" in { "Hello world" must endWith("world") autotest: } } $ ~ test } describe  "HelloWorldSpec"  do context  "The  'Hello  world'  string  should"  do    it  "contain 11 characters"  do rspec        "Hello  world".size.should  eq(11)    end    it  "end with 'world'"  do        "Hello  world".should  end_with("world") $ autospec    end end end
  • 24. In Procfile: Deploy web: target/start -Dhttp.port=${PORT} -DapplyEvolutions.default=true - Ddb.default.url=${DATABASE_URL} -Ddb.default.driver=org.postgresql.Driver In project/Build.scala: val appDependencies = Seq( "postgresql" % "postgresql" % "8.4-702.jdbc4" ) $ heroku create $ git push heroku master $  heroku  create $  git  push  heroku  master
  • 25. Adendo Scala X Ruby by @danicuki
  • 26. Lambda list.filter(_ < 100) list.select  do  |el|    el  <  100 list.filter { end   el: Int => (el < 100) }
  • 27. Types Static: Dynamic: val a = new a  =  Hash.new HashMap[Int, String] a  =  “BOO!”
  • 28. Pattern Matching require  'case' def  matchTest  x  case  x  when  7 def myMatch(x: Any): Any =      "seven" x match {  when  "string" case 7 => “seven”      0 case “string” => 0  when  Case::All[Integer] case y:Int => “no.” case 2 :: tail => tail      "no." }  when   Case::Array[2,Case::Any]      x[1..-­‐1]  end end
  • 29. Monkey Patch class MySuperString(original: String) { def myMethod = "yess!!!" } implicit def string2super(x: String) = new MySuperString(x) println("a".myMethod) // => yess!!! class  String    def  my_method      "yess!!!"    end end puts  "a".my_method  #  =>  yess!!!
  • 30. Dynamic Calls class Animal extends Dynamic { def _select_(name: String) = println("Animal says " + name) def _invoke_(name: String, args: Any*) = { println("Animal wants to " + name + args.mkString(", ")) this } val animal = new Animal } animal.qualk // => Animal says qualk animal.say("hello") // => Animal wants to say hello class  Animal    def  method_missing  name,  *args        if  args.empty?            puts  "Animal  says  "  +  name.to_s        else            puts  "Animal  wants  to  "  +  name.to_s  +    args.join(",  ")        end        self animal  =  Animal.new    end animal.qualk  #  =>  Animal  says  :  qualks  ! end animal.say("hello")  #  =>  Animal  wants  to  say  hello
  • 31. Modules / Traits trait PimpMyClass { def myMethod = println("myMethod") } class IncludeTrait extends PimpMyClass (new IncludeTrait).myMethod module  PimpMyClass    def  my_method        puts  "my_method"    end end class  IncludeModule    include  PimpMyClass end IncludeModule.new.my_method
  • 32. Duck Typing class Duck { def ActAsADuck(a: { def quack; def walk })= { def quack = ... a.quack def walk = ... a.walk } } class Platypus { val duck = new Duck def quack = ... val platypus = new Platypus def walk = ... ActAsADuck(duck) } ActAsADuck(platypus) class  Duck def  act_as_a_duck  animal    def  quack;  end    animal.quack    def  walk;  end    animal.walk end end class  Platypus duck  =  Duck.new    def  quack;  end platypus  =  Platypus.new    def  walk;  end act_as_a_duck(duck) end act_as_a_duck(platypus)
  • 34. Performance 80 70.74 Scala 60 JRuby Ruby 39.74 40 20 2.07 0 Source : http://shootout.alioth.debian.org
  • 35. References ✦ http://www.playframework.com/documentation ✦ http://guides.rubyonrails.org/ ✦ http://www.agileandart.com/ ✦ http://www.slideshare.net/El_Picador/scala-vs-ruby