merb
DESCRIPTION
All about MerbTRANSCRIPT
![Page 1: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/1.jpg)
merbkicking mvc into high gear
![Page 2: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/2.jpg)
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.
![Page 3: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/3.jpg)
what’s merb?
![Page 4: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/4.jpg)
web framework
![Page 5: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/5.jpg)
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.
![Page 6: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/6.jpg)
modular
![Page 7: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/7.jpg)
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.
![Page 8: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/8.jpg)
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.
![Page 9: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/9.jpg)
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.
![Page 10: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/10.jpg)
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.
![Page 11: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/11.jpg)
simplicity ftw
![Page 12: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/12.jpg)
MOTTO: no code is faster
than no code
![Page 13: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/13.jpg)
things you hear
![Page 14: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/14.jpg)
developer time is expensive
![Page 15: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/15.jpg)
servers are cheap
![Page 16: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/16.jpg)
ergo: efficiency doesn’t matter
![Page 17: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/17.jpg)
you can always throw more hardware at it
![Page 18: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/18.jpg)
And we at EY are happy to sell you hardware.
![Page 19: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/19.jpg)
but what if you could have both?
What if we didn’t have to choose between developer efficiency and machine efficiency?
![Page 20: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/20.jpg)
?
Would that be the holy grail?
![Page 21: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/21.jpg)
no, that’s merb.
![Page 22: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/22.jpg)
merb 0.9
![Page 23: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/23.jpg)
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)
![Page 24: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/24.jpg)
class ApiHandler def initialize(app) @app = app end
def call(env) ... endend
use ApiHandlerrun Merb::Rack::Application.new
Here’s an example Rack handler.
![Page 25: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/25.jpg)
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) endend
Here’s what the call method looks like. You return a tuple of [status_code, headers, body].
![Page 26: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/26.jpg)
router
Merb has a kick-ass router.
![Page 27: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/27.jpg)
Merb::Router.prepare do |r| r.resources :posts do |post| post.resources :comments endend
We support simple stuff, like resources or even nested resources.
![Page 28: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/28.jpg)
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.
![Page 29: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/29.jpg)
Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :user_agent => /MSIE/). to(:controller => “account”, :action => “login”, :id => “[1]”end
checks request.user_agent
Or any part of the Request object.
![Page 30: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/30.jpg)
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]”
![Page 31: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/31.jpg)
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.
![Page 32: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/32.jpg)
Merb::Router.prepare do |r| r.match(%r{/login/(.*)}, :protocol => “http://”). to(:controller => “account”, :action => “login”, :id => “[1]”end
![Page 33: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/33.jpg)
accepts header,meet provides
Your client tells Merb what it can accept. You tell Merb what a controller can provide.
![Page 34: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/34.jpg)
class Post < Application provides :json, :yaml
def show @post = Post[params[:id]] display @post endend
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.
![Page 35: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/35.jpg)
display flowdisplay @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.
![Page 36: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/36.jpg)
display flowdisplay @foo
get content_type
XML
Look for foo.xml.*
@foo.to_xmlno?
![Page 37: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/37.jpg)
display flowdisplay @foo
get content_type
XML
Look for foo.xml.*
@foo.to_xml
![Page 38: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/38.jpg)
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.
![Page 39: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/39.jpg)
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).
![Page 40: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/40.jpg)
Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :Encoding => "UTF-8")
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.
![Page 41: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/41.jpg)
class Post < Application provides :json, :yaml, :xml
def show @post = Post[params[:id]] display @post endend
Here’s the example again.
![Page 42: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/42.jpg)
class Post < Application provides :json, :yaml, :xml
def show(id) @post = Post[id] display @post endend
merb-action-args
We can use the merb-action-args to simplify our controllers.
![Page 43: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/43.jpg)
a benefit of modularity
Let’s take a look at an simple benefit of Merb’s modularity.
![Page 44: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/44.jpg)
class Mail < Merb::Mailer before :shared_behavior
def index render_mail endend
Mailers look the same as controllers.
![Page 45: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/45.jpg)
class Mail < Merb::Mailer before :shared_behavior
def index render_mail :foo endend
You can pass them a symbol, which will use a different template.
![Page 46: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/46.jpg)
class Mail < Merb::Mailer before :shared_behavior
def index render_mail :html => :foo, :text => :bar endend
You can also use special templates for html and text, without any fancy methods.
![Page 47: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/47.jpg)
class Mail < Merb::Mailer before :shared_behavior
def index attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar endend
You can attach a file, which will automatically figure out the mime and use it.
![Page 48: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/48.jpg)
class Mail < Merb::Mailer before :shared_behavior layout :mailers
def index attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar endend
You can use layouts, just like regular controllers.
![Page 49: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/49.jpg)
send_mail Mail, :index, {:to => “[email protected]”}
You call mailers in your controllers like this.
![Page 50: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/50.jpg)
class Mail < Merb::Mailer before :shared_behavior layout :mailers
def index attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar endend
![Page 51: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/51.jpg)
class Mail < Merb::Mailer before :shared_behavior layout :mailers
def index mail.to = [“[email protected]”] attach File.open(“/foo/bar”) render_mail :html => :foo, :text => :bar endend
You also have access to the raw mailer object (a MailFactory object).
![Page 52: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/52.jpg)
testing
What about testing?
![Page 53: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/53.jpg)
controllers are plain old ruby objects
You can test Merb objects like real Ruby objects.
![Page 54: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/54.jpg)
instantiated with new
![Page 55: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/55.jpg)
actions are methods
![Page 56: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/56.jpg)
they return data
![Page 57: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/57.jpg)
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 endend
This is the raw way of doing testing. You probably wouldn’t do this, and it uses a private method (_dispatch).
![Page 58: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/58.jpg)
describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json endend
You can use Merb’s helpers as well.
![Page 59: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/59.jpg)
describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json endend
controller
![Page 60: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/60.jpg)
describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json endend
action
![Page 61: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/61.jpg)
describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json endend
params
![Page 62: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/62.jpg)
describe MyController do it “returns some json” do dispatch_to( MyController, :index, {:foo => :bar}, {:accept => “application/json”} ) @controller.body.should == {:foo => :bar}.to_json endend
request environment
![Page 63: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/63.jpg)
getting started
![Page 64: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/64.jpg)
sake (edge)
The preferred way to keep up with Merb now is to use the sake tasks.
![Page 65: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/65.jpg)
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.
![Page 66: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/66.jpg)
gem install merb
You can also get the latest released gems from Rubyforge.
![Page 67: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/67.jpg)
merb-gen app my_app
This is the equivalent of rails my_app.
![Page 68: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/68.jpg)
init.rb
You’ll probably want to customize init.rb.
![Page 69: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/69.jpg)
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.
![Page 70: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/70.jpg)
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.
![Page 71: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/71.jpg)
before vs. before_filter
Controllers use before :foo instead of before_filter :foo.
![Page 72: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/72.jpg)
provides vs. respond_to
As shown above, we use a completely different API than Rails does for deciding what mime-type to return.
![Page 73: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/73.jpg)
:except vs. :exclude
We use before :foo, :except => :bar instead of before_filter :foo, :exclude => :bar
![Page 74: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/74.jpg)
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!
![Page 75: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/75.jpg)
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.
![Page 76: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/76.jpg)
url_for vs. url
We do url(:resource, @resource) instead of url_for_resource(@resource).
![Page 77: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/77.jpg)
css_include_tag :foo, :bundle => :basevs.
stylesheet_link_tag :foo, :bundle => :base
We use css_include_tag instead of stylesheet_link_tag. We also use js_include_tag for consistency.
![Page 78: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/78.jpg)
mailers
As shown above, our mailers are different (and much cooler).
![Page 79: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/79.jpg)
no rjs
We don’t use RJS. We recommend using Unobtrusive JavaScript techniques and a merb_jquery plugin along these lines is available.
![Page 80: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/80.jpg)
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.
![Page 81: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/81.jpg)
render returns string
![Page 82: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/82.jpg)
render :foo
render :foo renders a template, but ...
![Page 83: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/83.jpg)
render “foo”
render “foo” renders the string wrapped in the layout. Just “foo” renders the string itself.
![Page 84: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/84.jpg)
render_json
render :json => :... becomes render_json :...
![Page 85: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/85.jpg)
no render :json => ...
![Page 86: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/86.jpg)
it’s considered a bug if
There’s a bunch of notions that are typically not considered bugs, but which we do.
![Page 87: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/87.jpg)
★ symbol#to_proc
★ alias_method_chain
★ merb gets slower
★ private api use
★ public api change*
★ non-documented
★ params
★ options keys
★ returns
★ yields
it’s considered a bug
*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.
![Page 88: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/88.jpg)
thank you.
![Page 90: Merb](https://reader033.vdocuments.mx/reader033/viewer/2022042814/5559306cd8b42a4f3d8b4901/html5/thumbnails/90.jpg)
</railsconf>