Merb
Upcoming SlideShare
Loading in...5
×
 

Merb

on

  • 15,716 views

All about Merb

All about Merb

Statistics

Views

Total Views
15,716
Views on SlideShare
15,684
Embed Views
32

Actions

Likes
21
Downloads
270
Comments
3

10 Embeds 32

http://www.slideshare.net 13
http://www.linkedin.com 8
https://www.linkedin.com 3
http://communitybookmarking.com 2
http://sharethebar.com 1
http://bio-nanotechnology.com 1
http://webcache.googleusercontent.com 1
http://bodyrobotics.com 1
http://115.112.206.131 1
http://asianrobots.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

13 of 3 Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Merb Merb Presentation Transcript

    • merb kicking mvc into high gear
    • Booth 501 I work for Engine Yard. They help fund projects like Merb and Rubinius, and allow me to spend time making DataMapper better. They rock.
    • what’s merb?
    • web framework
    • emphasizes efficiency and hackability Instead of emphasizing a complete, monolithic framework with everything built in for the 80-20 case, Merb emphasizes making it easy to build what you need. That doesn’t mean we don’t want to make it easy to get started. Merb’s defaults provide the get-up-and-running feel that you get from more monolithic frameworks.
    • modular
    • improved api We try to learn from other frameworks in Ruby and in the programming world at large. When we find something we like, we use it. When we find something we think we can make easier to interact with, we do that.
    • give you as much headroom as possible Our goal is to maintain as small a footprint as possible to give your app more system resources to use.
    • no &:sym in merb For instance, we don’t use Symbol#to_proc inside Merb, which is a convenience but dramatically slows down operations that use it.
    • slowdowns are a bug Slowdowns are not unfortunate. They are a bug. If you notice that a commit to Merb makes it slower, file a ticket on LightHouse. We will take it seriously.
    • simplicity ftw
    • MOTTO: no code is faster than no code
    • things you hear
    • developer time is expensive
    • servers are cheap
    • ergo: efficiency doesn’t matter
    • you can always throw more hardware at it
    • And we at EY are happy to sell you hardware.
    • but what if you could have both? What if we didn’t have to choose between developer efficiency and machine efficiency?
    • ? Would that be the holy grail?
    • no, that’s merb.
    • merb 0.9
    • based on rack Rack is based on Python’s WSGY, which allows a web framework like Merb to interact with a bunch of web servers (like Mongrel, Thin, Ebb, Webrick, CGI, FastCGI)
    • class ApiHandler def initialize(app) @app = app end def call(env) ... end end use ApiHandler run Merb::Rack::Application.new Here’s an example Rack handler.
    • def call(env) request = Merb::Request.new if request.path =~ %r{/api/(.*)} [200, {“Content-Type” => “text/json”}, Api.get_json($1)] else @app.call(env) end end Here’s what the call method looks like. You return a tuple of [status_code, headers, body].
    • router Merb has a kick-ass router.
    • Merb::Router.prepare do |r| r.resources :posts do |post| post.resources :comments end end We support simple stuff, like resources or even nested resources.
    • Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :user_agent => /MSIE/). to(:controller => “account”, :action => “login”, :id => “[1]” end But we also support regexen.
    • Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :user_agent => /MSIE/). to(:controller => “account”, checks request.user_agent :action => “login”, :id => “[1]” end Or any part of the Request object.
    • Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :user_agent => /MSIE/). to(:controller => “account”, :action => “login”, :id => “[1]” end You can use any capture from your regex in #to hashes via “[capture_number]”
    • Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :method => “post”). to(:controller => “account”, :action => “login”, :id => “[1]” end Here’s another example of using the Request object.
    • Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :protocol => “http://”). to(:controller => “account”, :action => “login”, :id => “[1]” end
    • accepts header, meet provides Your client tells Merb what it can accept. You tell Merb what a controller can provide.
    • class Post < Application provides :json, :yaml def show @post = Post[params[:id]] display @post end end Here, you tell Merb to provide JSON and YAML. Then, you tell it to serialize the @post object into the appropriate form depending on what the client requested.
    • display flow display @foo get content_type XML Look for foo.xml.* yes render Here’s how Merb determines what to render given a specific parameter to display. This workflow assumes the client asked for XML.
    • display flow display @foo get content_type XML Look for foo.xml.* @foo.to_xml no?
    • display flow display @foo get content_type XML Look for foo.xml.* @foo.to_xml
    • default mimes In order to make this work simply and seamlessly, we need Merb to know about a set of default mime types. Here’s the list.
    • Merb.add_mime_type(:all, nil, %w[*/*]) Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml]) Merb.add_mime_type(:text, :to_text, %w[text/plain]) Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html]) The first parameter is the internal name for the mime used by Merb. It is also the extension to use for a URL if you want that mime to be used (http://foo.com/index.json will use the :json type).
    • Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :Encoding => quot;UTF-8quot;) Merb.add_mime_type(:js, :to_json, %w[text/javascript application/javascript application/x-javascript]) Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json]) The second parameter is an Array of mime types from the Accept header that will match the mime. The first item in the list is the mime-type that will be returned to the client.
    • class Post < Application provides :json, :yaml, :xml def show @post = Post[params[:id]] display @post end end Here’s the example again.
    • class Post < Application provides :json, :yaml, :xml def show(id) @post = Post[id] merb-action-args display @post end end We can use the merb-action-args to simplify our controllers.
    • a benefit of modularity Let’s take a look at an simple benefit of Merb’s modularity.
    • class Mail < Merb::Mailer before :shared_behavior def index render_mail end end Mailers look the same as controllers.
    • class Mail < Merb::Mailer before :shared_behavior def index render_mail :foo end end You can pass them a symbol, which will use a different template.
    • class Mail < Merb::Mailer before :shared_behavior def index render_mail :html => :foo, :text => :bar end end You can also use special templates for html and text, without any fancy methods.
    • class Mail < Merb::Mailer before :shared_behavior def index attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar end end You can attach a file, which will automatically figure out the mime and use it.
    • class Mail < Merb::Mailer before :shared_behavior layout :mailers def index attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar end end You can use layouts, just like regular controllers.
    • send_mail Mail, :index, {:to => “wycats@gmail.com”} You call mailers in your controllers like this.
    • class Mail < Merb::Mailer before :shared_behavior layout :mailers def index attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar end end
    • class Mail < Merb::Mailer before :shared_behavior layout :mailers def index mail.to = [“wycats@gmail.com”] attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar end end You also have access to the raw mailer object (a MailFactory object).
    • testing What about testing?
    • controllers are plain old ruby objects You can test Merb objects like real Ruby objects.
    • instantiated with new
    • actions are methods
    • they return data
    • describe MyController do it “returns some json” do @mock = fake_request( :accept => “application/json”) c = MyController.new(@mock) c._dispatch(:index).should == {:foo => “bar”}.to_json end end This is the raw way of doing testing. You probably wouldn’t do this, and it uses a private method (_dispatch).
    • describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json end end You can use Merb’s helpers as well.
    • describe MyController do it “returns some json” do dispatch_to( MyController, :index, controller {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json end end
    • describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => action :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json end end
    • describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept params “application/json”} => ) @controller.body.should == {:foo => :bar}.to_json end end
    • describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) request environment @controller.body.should == {:foo => :bar}.to_json end end
    • getting started
    • sake (edge) The preferred way to keep up with Merb now is to use the sake tasks.
    • sudo gem install sake sake -i http://merbivore.com/merb-dev.sake mkdir ~/merb_sources cd ~/merb_sources sake merb:clone sake merb:install sake merb:upate # later Do this.
    • gem install merb You can also get the latest released gems from Rubyforge.
    • merb-gen app my_app This is the equivalent of rails my_app.
    • init.rb You’ll probably want to customize init.rb.
    • use_orm :datamapper use_test :rspec dependency “merb_more” # or what you need ... other dependencies ... Merb::BootLoader.before_app_loads do DataMapper.setup(:salesforce, ...) end Use before_app_loads for things that need to know about the structure of the framework (where your controllers/models/etc. are). The dependency method automatically handles the appropriate time to load the plugin.
    • merb != Rails We’ve had a lot of back-and-forth about things that are not the same between Merb and Rails. Here’s a list of things that you should be aware of when coming from a Rails background.
    • before vs. before_filter Controllers use before :foo instead of before_filter :foo.
    • provides vs. respond_to As shown above, we use a completely different API than Rails does for deciding what mime-type to return.
    • :except vs. :exclude We use before :foo, :except => :bar instead of before_filter :foo, :exclude => :bar
    • logger vs. merb.logger We do not have a Kernel method for our logger. You get access to our logger by doing Merb.logger.info!
    • fooscontroller vs. foos Since we don’t use const_missing to figure out where to load things, there are no naming requirements for any class. All classes are loaded at boot-time.
    • url_for vs. url We do url(:resource, @resource) instead of url_for_resource(@resource).
    • css_include_tag :foo, :bundle => :base vs. stylesheet_link_tag :foo, :bundle => :base We use css_include_tag instead of stylesheet_link_tag. We also use js_include_tag for consistency.
    • mailers As shown above, our mailers are different (and much cooler).
    • no rjs We don’t use RJS. We recommend using Unobtrusive JavaScript techniques and a merb_jquery plugin along these lines is available.
    • mandatory render Merb actions return strings. This provides massive additional flexibility when using actions from other methods. Our render method just returns a string, and is thus required at the end of actions.
    • render returns string
    • render :foo render :foo renders a template, but ...
    • render “foo” render “foo” renders the string wrapped in the layout. Just “foo” renders the string itself.
    • render_json render :json => :... becomes render_json :...
    • no render :json => ...
    • it’s considered a bug if There’s a bunch of notions that are typically not considered bugs, but which we do.
    • it’s considered a bug ★ symbol#to_proc ★ non-documented ★ alias_method_chain ★ params ★ merb gets slower ★ options keys ★ private api use ★ returns ★ public api change* ★ yields *without deprecation period and notice in public API changelog alias_method_chain is ok in your app code, but it’s a bug if we use it in Merb.
    • thank you.
    • any questions? Feel free to comment on this blog post or email me at wycats@gmail.com.
    • </railsconf>