Deciphering Rails 3 with Gregg Pollack
asi        c        to                     r         edi# B        ded        an d R                              _s     r...
Deciphering Rails 3       Method Compilation Microkernel Architecturealias_method_chain vs super     ActiveSupport::Concer...
let’s test t he water
Basics                                def city                                        return @city                        ...
evalhash = {name => Toaster, location => Moscow}hash.each_pair do |key, value|  eval <<-RUBY                         @name...
instan ce_eval class Test                                     t = Test.new   def print                                    ...
c lass_eval   class Test         class Test   end                end   class Test         Test.class_eval do     def print...
Me thod Com pilation
s = SimplePrint.new [:push_it, :pop_it, :top_it]                                                         outputs.push_its....
s = SimplePrint.new [:push_it, :pop_it, :top_it]30000.times do  s.push_it  s.pop_it  s.top_itend     Using Method Missing ...
s = SimplePrint.new [:push_it, :pop_it, :top_it]class SimplePrint                           class BetterPrint  attr_access...
[:push_it, :pop_it, :top_it]class BetterPrint  def initialize(arr)         def push_it    arr.each do |meth|          prin...
s = SimplePrint.new [:push_it, :pop_it, :top_it]30000.times do  s.push_it  s.pop_it  s.top_itend     Using Method Missing ...
ruby-profUsing Method MissingUsing Method Compliation
Yehuda’s first commitrails/actionpack/lib/abstract_controller/metal/mime_responds.rb      rails/actionpack/lib/abstract_co...
ActiveSupport Callbacks  Refactored for Speed  Used in ActionPack, Test::Unit, and ActionController   before_filter :authe...
method compliation    class PostsController < ApplicationController      layout custom    end  layout :symbol  layout proc...
method compliation  rails/actionpack/lib/abstract_controller/layouts.rb layout_definition = case _layout   when String    ...
Me thod Com pilation
let’s test t he water
includin g modules                      module PrintMeth                        def print                          puts "R...
nel Arch itectureM icroker
AbstractController    A refactor of ActionController in ActionPack          Provides	  A	  Low	  Level	  Interface	  for	 ...
Old ActionController Stack    Microkernel Design Pattern   Cookies                   ActionDispatch              S       R...
Old ActionController Stack    Microkernel Design Pattern   Cookies   Assigns                    AbstractController        ...
Microkernel Design Pattern  AbstractController  Assigns  Callbacks  Collector  Helpers  Layouts  Logger  Rendering  Transl...
The MicroKernel   rails/actionpack/lib/abstract_controller/base.rb    module AbstractController      class Base        att...
AbstractController::BaseThe microkernel with the bare minimum needed for dispatching         Assigns                      ...
Microkernel Design Pattern   ActionController::Metal   << AbstractController::Base                                        ...
Microkernel Design Pattern   ActionController::Metal     << AbstractController::Baseapp/controllers/hello_controller.rb cl...
ActionController::Base                           Microkernel Design Pattern          rails/actionpack/lib/action_controlle...
Cookies                                 Exceptions                                 Flash    ActionController::Metal      H...
Microkernel Design Patternapp/controllers/hello_controller.rb class HelloController < ActionController::Metal   include Ac...
ActionController::Base                        Microkernel Design Patternrails/actionpack/lib/action_controller/base.rbmodu...
includes ActionController::Base             abstract                        ActionController Namespace                    ...
nel Arch itectureM icroker
asi        c        to                     r         edi# B        ded        an d R                              _s     r...
let’s test t he water
Both instance and class methods  module PrintMeth                class Test    def self.included(base)         include Pri...
d_chain vs superalia s_metho
Can’t modify parent class class GenericUser          mr   def name name_  without_     "Gregg Pollack"   end end          ...
Can’t modify parent class class GenericUser          mr   def name name_  without_     "Gregg Pollack"   end end          ...
class GenericUser   def name     "Gregg Pollack"   end end                       module Mr                             def...
AbstractController    A refactor of ActionController in ActionPack          Provides	  A	  Low	  Level	  Interface	  for	 ...
ActionController::Base                        Microkernel Design Patternrails/actionpack/lib/action_controller/base.rbmodu...
Using Superrails/actionpack/lib/abstract_controller/helpers.rb module AbstractController   module Helpers       # Returns ...
thod_chain vs supera lias_me
upport:: ConcernActiveS
class MyBar                   module MyCamp   cattr_accessor :year                                 def self.included(klass...
module MyCamp                module MyCamp                               extend ActiveSupport::Concern  def self.included(...
When a module with ActiveSupport::Concern      gets included into a class, it will:1. Look for ClassMethods and extend the...
When a module with ActiveSupport::Concern      gets included into a class, it will:2. Look for InstanceMethods and include...
When a module with ActiveSupport::Concern      gets included into a class, it will:3. class_eval everything in the include...
4. All included modules get their included hookrun on the base classmodule MyFoo  extend ActiveSupport::Concern           ...
ActionController::Base                        Microkernel Design Patternrails/actionpack/lib/action_controller/base.rbmodu...
rails/actionpack/lib/abstract_controller/helpers.rb  module AbstractController    module Helpers      extend ActiveSupport...
upport::C oncern     ActiveS1. Look for ClassMethods and extend them2. Look for InstanceMethods and include them3. class_e...
hrow in B undlerCatch/T
Dependency Resolution   Depth	  First	  Search                                dependencies           paperclip            ...
Control Flow   if	        method	  return   elsif	     method	  invocation   else   unless   for         raise	  ..	  resc...
Control Flow   catch(:marker) do     puts "This will get executed"     throw :marker     puts "This will not get executed"...
Dependency Resolution   Depth	  First	  Search                                dependencies           paperclip            ...
Inside Bundler                     Bundler/lib/bundler/resolver.rb      when resolving a requirement   retval = catch(requ...
hrow in B undlerCatch/T
Deciphering Rails 3       Method Compilation Microkernel Architecturealias_method_chain vs super     ActiveSupport::Concer...
asi        c        to                     r         edi# B        ded        an d R                              _s     r...
Creative Commons           name                     author                               URLConstruction Time Again     v1...
http://RailsBest.com
Slides => http://bit.ly/railstoasterСпасибо          @GreggPollack       Gregg@EnvyLabs.com        http://envylabs.com
Upcoming SlideShare
Loading in...5
×

Decyphering Rails 3

1,370

Published on

Код ядра Rails был существенно улучшен с выпуском Rails 3, в основном из-за использования эффективных паттернов проектирования. Мы разберем некоторые из ключевых изменений, которые привели к улучшению качества кода, и на их примере научимся применять такие техники к своему собственному коду.

Вот некоторые из таких техник:

Компилирование методов vs method_missing
Микроядерная архитектура
alias_method_chain vs super
ActiveSupport::Concern
Catch/Throw в Bundler

Слушатели намного улучшат свои знания о некоторых сложных паттернах проектирования в Ruby и станут лучше разбираться во внутренностях Rails 3.

Published in: Technology, Design
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,370
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
18
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Decyphering Rails 3

  1. 1. Deciphering Rails 3 with Gregg Pollack
  2. 2. asi c to r edi# B ded an d R _s r ovi er er e .to # p end pe) = typ R ty in e =( e "] # t_t yp Typ ten te nt- con [" Con def d ers hea end "] ype ype t_t t-T on ten on ten f c [" C source de rs ade ng the he end raid of readi ion ion "] be af at at loc Loc Don’t def [" d ers hea rl e nd (u rl) = u on= n"] a ti ca tio loc "Lo def s[ derDon’t be afraid of making it your own hea end us tus ) s tat sta def ta tus co de( @_s at us_ tu s) ls .st end sta Uti =( :: l] a tus R ack [va st = : def t a tus ? val @_s ) ch) val ea end od y =( to ?(: ns e_b po nd_ e spo . res
  3. 3. Deciphering Rails 3 Method Compilation Microkernel Architecturealias_method_chain vs super ActiveSupport::Concern Catch/Throw in Bundler
  4. 4. let’s test t he water
  5. 5. Basics def city return @city endclass SimplePrint attr_accessor :city def city=(val) def initialize(val) @city = val self.city = val end end def method_missing(meth) s = SimplePrint.new("moscow") puts "#{meth} #{city}" endend s.toaster> s = SimplePrint.new("moscow") => #<SimplePrint:0x000001020013d0 @city="moscow">> s.toastertoaster moscow => nil
  6. 6. evalhash = {name => Toaster, location => Moscow}hash.each_pair do |key, value| eval <<-RUBY @name = Toaster @#{key} = value RUBYend @location = Moscowputs @name + @locationToasterMoscow
  7. 7. instan ce_eval class Test t = Test.new def print t.print puts "Hello" Hello end end Test.new.instance_eval do t = Test.new print t.instance_eval do end def print2 Hello puts "Hello2" b6 0> end 0 0124 t :0 x1 end r# <Tes Test.new.print2 rin t 2’ fo eth od ‘p t.print2 d m u nd efine r: dErro Hello2 M etho No
  8. 8. c lass_eval class Test class Test end end class Test Test.class_eval do def print def print puts "Ruby5" puts "Ruby5" end end end end Test.new.print Test.new.print Ruby5 Ruby5
  9. 9. Me thod Com pilation
  10. 10. s = SimplePrint.new [:push_it, :pop_it, :top_it] outputs.push_its.pop_it => “called push_it”s.top_it => “called pop_it” => “called top_it”class SimplePrint attr_accessor :actions def initialize(arr) self.actions = arr end def print(meth) puts "called #{meth}" end def method_missing(meth) print(meth) if actions.include? meth endend
  11. 11. s = SimplePrint.new [:push_it, :pop_it, :top_it]30000.times do s.push_it s.pop_it s.top_itend Using Method Missing 5 Seconds
  12. 12. s = SimplePrint.new [:push_it, :pop_it, :top_it]class SimplePrint class BetterPrint attr_accessor :actions def initialize(arr) def initialize(arr) arr.each do |meth| self.actions = arr end instance_eval <<-RUBY def #{meth} def print(meth) print("#{meth}") puts "called #{meth}" end end RUBY def method_missing(meth) end print(meth) if actions.include? meth end endend def print(meth) puts "called #{meth}" end end
  13. 13. [:push_it, :pop_it, :top_it]class BetterPrint def initialize(arr) def push_it arr.each do |meth| print("push_it") end instance_eval <<-RUBY def #{meth} print("#{meth}") end def pop_it RUBY print("pop_it") end end end def print(meth) def top_it puts "called #{meth}" print("top_it") end endend
  14. 14. s = SimplePrint.new [:push_it, :pop_it, :top_it]30000.times do s.push_it s.pop_it s.top_itend Using Method Missing 5 Seconds Using Instance Eval 3.5 Seconds 30 % Faster!
  15. 15. ruby-profUsing Method MissingUsing Method Compliation
  16. 16. Yehuda’s first commitrails/actionpack/lib/abstract_controller/metal/mime_responds.rb rails/actionpack/lib/abstract_controller/collector.rb
  17. 17. ActiveSupport Callbacks Refactored for Speed Used in ActionPack, Test::Unit, and ActionController before_filter :authenticate after_filter :fetch_extra_data around_filter :transaction skip_filter :admin_only, :except => [:new] 10x Faster with method compilation
  18. 18. method compliation class PostsController < ApplicationController layout custom end layout :symbol layout proc{ |c| c.logged_in? ? "member" : "non-member" } layout false layout nil Are  you  a  string,  symbol,  proc,  boolean,  or  nil?
  19. 19. method compliation rails/actionpack/lib/abstract_controller/layouts.rb layout_definition = case _layout when String _layout.inspect when Proc define_method :_layout_from_proc, &_layout "_layout_from_proc(self)" when false nil when true raise ArgumentError when nil name_clause end self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout #{layout_definition} end private :_layout RUBY
  20. 20. Me thod Com pilation
  21. 21. let’s test t he water
  22. 22. includin g modules module PrintMeth def print puts "Ruby5" end end As Instance Method As Class Method class Test class Test include PrintMeth extend PrintMeth end end Test.new.print Test.print Ruby5 Ruby5
  23. 23. nel Arch itectureM icroker
  24. 24. AbstractController A refactor of ActionController in ActionPack Provides  A  Low  Level  Interface  for   making  Customized  Controller  Base  classes. Carl Lerche
  25. 25. Old ActionController Stack Microkernel Design Pattern Cookies ActionDispatch S Routeression Layout s Logger MimeRes ponds s Cal lback Rendere r url_for http_ auth helpers
  26. 26. Old ActionController Stack Microkernel Design Pattern Cookies Assigns AbstractController Sessio Layout Callbacks n s Collector Logger MimeRes Helpers ponds Layouts Logger ks ac Callb Renderinge R nderer Translation url_for ViewPaths http_ auth helpers
  27. 27. Microkernel Design Pattern AbstractController Assigns Callbacks Collector Helpers Layouts Logger Rendering Translation ViewPaths
  28. 28. The MicroKernel rails/actionpack/lib/abstract_controller/base.rb module AbstractController class Base attr_internal :response_body attr_internal :action_name abstract! # Calls the action going through the entire action dispatch stack. def process(action, *args) def controller_path def action_methods private def action_method?(name) def process_action(method_name, *args) def _handle_action_missing def method_for_action(action_name) end end
  29. 29. AbstractController::BaseThe microkernel with the bare minimum needed for dispatching Assigns before_filter :authorized Callbacks after_filter :send_email Collector around_filter :benchmark helper :custom Helpers helper_method :current_user layout custom Layouts layout :symbol Logger layout false layout nil Rendering Translation ViewPaths Modules that can be included to add functionality on top of base
  30. 30. Microkernel Design Pattern ActionController::Metal << AbstractController::Base Assigns Base Callbackscontains just enough code to get a valid Collector Rack application from a controller Helpers Layouts Logger Rendering Translation ViewPaths ActionMailer::Base << AbstractController::Base
  31. 31. Microkernel Design Pattern ActionController::Metal << AbstractController::Baseapp/controllers/hello_controller.rb class HelloController < ActionController::Metal def index self.response_body = "Hello World!" end endconfig/routes.rb match hello, :to => HelloController.action(:index)
  32. 32. ActionController::Base Microkernel Design Pattern rails/actionpack/lib/action_controller/metal.rb module ActionController class Metal < AbstractController::Base abstract!request def self.call(env) action(env[...][:action]).call(env) end def self.action(name, klass = ActionDispatch::Request) middleware_stack.build do |env| new.dispatch(name, klass.new(env)) end end def dispatch(name, request) @_request = request @_env = request.env @_env[action_controller.instance] = self process(name) response ? response.to_a : [status, headers, response_body] end end end
  33. 33. Cookies Exceptions Flash ActionController::Metal Helpers Redirecting Renderingredirect_to post_url(@post) Responder UrlForclass PeopleController < ApplicationController ..... (lots more) respond_to :html, :xml, :json def index @people = Person.find(:all) Assigns respond_with(@people) end Callbacksend Collector Helpers AbstractController::Base Layouts Logger Rendering Translation ViewPaths
  34. 34. Microkernel Design Patternapp/controllers/hello_controller.rb class HelloController < ActionController::Metal include ActionController::Rendering append_view_path "#{Rails.root}/app/views" def index render "hello/index" end endapp/controllers/hello_controller.rbclass HelloController < ActionController::Metal include ActionController::Redirecting include Rails.application.routes.url_helpers def index redirect_to root_url endend
  35. 35. ActionController::Base Microkernel Design Patternrails/actionpack/lib/action_controller/base.rbmodule ActionController class Base < Metal abstract! MODULES = [ AbstractController::Layouts, AbstractController::Translation, module ActionController Cookies, Helpers, Flash, module Helpers HideActions, Verification, UrlFor, RequestForgeryProtection, include AbstractController::Helpers Streaming, Redirecting, ... RecordIdentifier, Rendering, Renderers::All, Instrumentation, ConditionalGet, AbstractController::Callbacks, RackDelegation, Rescue SessionManagement, ] Caching, MimeResponds, MODULES.each do |mod| PolymorphicRoutes, include mod ImplicitRender, end
  36. 36. includes ActionController::Base abstract ActionController Namespace Cookies Exceptions Flash Helpers ActionController::Metal Redirecting Rendering abstract Responder UrlFor ..... (lots more) AbstractController Namespace Assigns Callbacks Collector HelpersAbstractController::Base Layouts Logger abstract Rendering Translation ViewPaths
  37. 37. nel Arch itectureM icroker
  38. 38. asi c to r edi# B ded an d R _s r ovi er er e .to # p end pe) = typ R ty in e =( e "] # t_t yp Typ ten te nt- con [" Con def d ers hea end "] ype ype t_t t-T on ten on ten de f c rs [" C he ade end "] ion ion source at at loc Loc ing the def [" ers f read d hea fraid o rl rl) = u t be a e nd (u n"] Don’ ti on= tio loc a ca s[ "Lo def der hea end us tus ) s tat sta def ta tus co de( @_s at us_ tu s) ls .st end sta Uti =( :: l] a tus R ack [va st = : def t a tus ? val @_s ) ch) val ea end od y =( to ?(: ns e_b po nd_ e spo . res
  39. 39. let’s test t he water
  40. 40. Both instance and class methods module PrintMeth class Test def self.included(base) include PrintMeth end ? base.class_eval do base.extend(ClassMethods) extend ClassMethods end Test.new.print_podcast end Test.print_company def print_podcast Ruby5 puts "Ruby5" Envy Labs end module ClassMethods def print_company puts "Envy Labs" end end end
  41. 41. d_chain vs superalia s_metho
  42. 42. Can’t modify parent class class GenericUser mr def name name_ without_ "Gregg Pollack" end end module Mr def name_with_mr na me "Mr. " + name_without_mr endclass User < GenericUser include Mr def self.included(base)end base.class_eval do alias :name_without_mr :nameputs User.new.name alias :name :name_with_mr end end output=> “Gregg Pollack” end output wanted=> “Mr. Gregg Pollack”
  43. 43. Can’t modify parent class class GenericUser mr def name name_ without_ "Gregg Pollack" end end module Mr def name_with_mr na me "Mr. " + name_without_mr endclass User < GenericUser include Mr def self.included(base)end base.class_eval do alias :name_without_mr :nameputs User.new.name alias :name :name_with_mr end end output=> “Gregg Pollack” end output wanted alias_method_chain :name, :mr=> “Mr. Gregg Pollack”
  44. 44. class GenericUser def name "Gregg Pollack" end end module Mr def name "Mr. " + superclass User < GenericUser end include Mrend endputs User.new.name output=> “Gregg Pollack” output wanted=> “Mr. Gregg Pollack”
  45. 45. AbstractController A refactor of ActionController in ActionPack Provides  A  Low  Level  Interface  for   making  Customized  Controller  Base  classes. Carl Lerche
  46. 46. ActionController::Base Microkernel Design Patternrails/actionpack/lib/action_controller/base.rbmodule ActionController class Base < Metal abstract! MODULES = [ AbstractController::Layouts, AbstractController::Translation, module ActionController Cookies, Helpers, Flash, module Helpers HideActions, Verification, UrlFor, RequestForgeryProtection, include AbstractController::Helpers Streaming, Redirecting, ... RecordIdentifier, Rendering, Renderers::All, Instrumentation, ConditionalGet, AbstractController::Callbacks, RackDelegation, Rescue SessionManagement, ] Caching, MimeResponds, MODULES.each do |mod| PolymorphicRoutes, include mod ImplicitRender, end
  47. 47. Using Superrails/actionpack/lib/abstract_controller/helpers.rb module AbstractController module Helpers # Returns a list of modules, normalized from the acceptable kinds of # helpers with the following behavior: def modules_for_helpers(args) ...rails/actionpack/lib/action_controller/metal/helpers.rb module ActionController helper : module Helpers all def modules_for_helpers(args) args += all_application_helpers if args.delete(:all) super(args) end ...
  48. 48. thod_chain vs supera lias_me
  49. 49. upport:: ConcernActiveS
  50. 50. class MyBar module MyCamp cattr_accessor :year def self.included(klass) include MyCamp klass.class_eval do self.year = "2010" def self.unconference extend ClassMethods ? puts title + " " + year end end end end module ClassMethods MyBar.unconference def title "BarCamp" endBarCamp 2010 end=> nil end
  51. 51. module MyCamp module MyCamp extend ActiveSupport::Concern def self.included(klass) klass.class_eval do included do self.year = "2010" self.year = "2010" extend ClassMethods end end module ClassMethods end def title "BarCamp" module ClassMethods end def title end "BarCamp" end end endend
  52. 52. When a module with ActiveSupport::Concern gets included into a class, it will:1. Look for ClassMethods and extend them module MyCamp extend ActiveSupport::Concern class MyBar include MyCamp module ClassMethods } def title end "BarCamp" end end end
  53. 53. When a module with ActiveSupport::Concern gets included into a class, it will:2. Look for InstanceMethods and include them module MyCamp extend ActiveSupport::Concern class MyBar include MyCamp module InstanceMethods } def title end "BarCamp" end end end
  54. 54. When a module with ActiveSupport::Concern gets included into a class, it will:3. class_eval everything in the include block module MyCamp extend ActiveSupport::Concern class MyBar include MyCamp } included do self.year = "2010" end end end
  55. 55. 4. All included modules get their included hookrun on the base classmodule MyFoo extend ActiveSupport::Concern } included do self.planet = "Earth" end class MyBarend include MyCamp endmodule MyCamp extend ActiveSupport::Concern include MyFoo Previously you had to do } class MyBar included do self.year = "2010" include MyFoo,MyCamp endend end
  56. 56. ActionController::Base Microkernel Design Patternrails/actionpack/lib/action_controller/base.rbmodule ActionController class Base < Metal abstract! MODULES = [ AbstractController::Layouts, AbstractController::Translation, module ActionController Cookies, Helpers, Flash, module Helpers HideActions, Verification, UrlFor, RequestForgeryProtection, include AbstractController::Helpers Streaming, Redirecting, ... RecordIdentifier, Rendering, Renderers::All, Instrumentation, ConditionalGet, AbstractController::Callbacks, RackDelegation, Rescue SessionManagement, ] Caching, MimeResponds, MODULES.each do |mod| PolymorphicRoutes, include mod ImplicitRender, end
  57. 57. rails/actionpack/lib/abstract_controller/helpers.rb module AbstractController module Helpers extend ActiveSupport::Concern } included do class_attribute :_helpers delegate :_helpers, :to => :self.class self._helpers = Module.new ../action_controller/base.rb end module ActionController class Base < Metalrails/actionpack/lib/action_controller/metal/helpers.rb include Helpers module ActionController module Helpers extend ActiveSupport::Concern include AbstractController::Helpers } included do class_attribute :helpers_path self.helpers_path = [] end ...
  58. 58. upport::C oncern ActiveS1. Look for ClassMethods and extend them2. Look for InstanceMethods and include them3. class_eval everything in the include block4. All included modules get their included hookrun on the base class
  59. 59. hrow in B undlerCatch/T
  60. 60. Dependency Resolution Depth  First  Search dependencies paperclip searchlogic shoulda sqlite3 aws-s3 activerecord Conflict mocha rake-compiler
  61. 61. Control Flow if   method  return elsif   method  invocation else unless for raise  ..  rescue while case catch  ..  throw
  62. 62. Control Flow catch(:marker) do puts "This will get executed" throw :marker puts "This will not get executed" end begin .. This will get executed => nil raise .. catch(:marker) do rescue puts "This will get executed" .. throw :marker, "hello" end puts "This will not get executed" end This will get executed => "hello"
  63. 63. Dependency Resolution Depth  First  Search dependencies paperclip searchlogic shoulda sqlite3 aws-s3 activerecord Conflict mocha rake-compiler
  64. 64. Inside Bundler Bundler/lib/bundler/resolver.rb when resolving a requirement retval = catch(requirement.name) do resolve(reqs, activated) end when activated gem is conflicted to go to initial requirement parent = current.required_by.last || existing.required_by.last debug { " -> Jumping to: #{parent.name}" } throw parent.name, existing.required_by.last.name when gem is not activated, but it’s dependencies conflict parent = current.required_by.last || existing.required_by.last debug { " -> Jumping to: #{parent.name}" } throw parent.name, existing.required_by.last.name
  65. 65. hrow in B undlerCatch/T
  66. 66. Deciphering Rails 3 Method Compilation Microkernel Architecturealias_method_chain vs super ActiveSupport::Concern Catch/Throw in Bundler
  67. 67. asi c to r edi# B ded an d R _s r ovi er er e .to # p end pe) = typ R ty in e =( e "] # t_t yp Typ ten te nt- con [" Con def d ers hea end "] ype ype t_t t-T on ten on ten f c [" C source de rs ade ng the he end raid of readi ion ion "] be af at at loc Loc Don’t def [" d ers hea rl e nd (u rl) = u on= n"] a ti ca tio loc "Lo def s[ derDon’t be afraid of making it your own hea end us tus ) s tat sta def ta tus co de( @_s at us_ tu s) ls .st end sta Uti =( :: l] a tus R ack [va st = : def t a tus ? val @_s ) ch) val ea end od y =( to ?(: ns e_b po nd_ e spo . res
  68. 68. Creative Commons name author URLConstruction Time Again v1ctory_1s_m1ne http://www.flickr.com/photos/v1ctory_1s_m1ne/3416173688/Microprocesseur Stéfan http://www.flickr.com/photos/st3f4n/2389606236/chain-of-14-cubes.4 Ardonik http://www.flickr.com/photos/ardonik/3273300715/(untitled) squacco http://www.flickr.com/photos/squeakywheel/454111821/up there Paul Mayne http://www.flickr.com/photos/paulm/873641065/Day 5/365 - Night Terrors Tom Lin :3= http://www.flickr.com/photos/tom_lin/3193080175/Testing the water The Brit_2 http://www.flickr.com/photos/26686573@N00/2188837324/High Dive Zhao Hua Xi Shi http://www.flickr.com/photos/elephantonabicycle/4321415975/
  69. 69. http://RailsBest.com
  70. 70. Slides => http://bit.ly/railstoasterСпасибо @GreggPollack Gregg@EnvyLabs.com http://envylabs.com
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×