Download - Lazy Loading and Object Proxying Shenangians

Transcript
Page 1: Lazy Loading and Object Proxying Shenangians

Lazy Loading..and object proxying shenanigans

Page 2: Lazy Loading and Object Proxying Shenangians

John Bartonwww.whoisjohnbarton.com

@johnbarton

Page 3: Lazy Loading and Object Proxying Shenangians

we’re often* hiring

* a month or two ago, right now, a couple of months from now

Page 4: Lazy Loading and Object Proxying Shenangians

The Problem:

Page 5: Lazy Loading and Object Proxying Shenangians

To handle ever increasing page load through the

judicious application of view fragment caching...

Page 6: Lazy Loading and Object Proxying Shenangians

... without resorting to downright ugly code

Page 7: Lazy Loading and Object Proxying Shenangians

For Example:

Page 8: Lazy Loading and Object Proxying Shenangians

class PostController < ApplicationController def index @posts = Post.all endend

Page 9: Lazy Loading and Object Proxying Shenangians

<% @posts.each do |post| %> <%= post.title %><% end %>

Page 10: Lazy Loading and Object Proxying Shenangians

Make it fast:

Page 11: Lazy Loading and Object Proxying Shenangians

<% cache 'slow_posts' do %> <% @posts.each do |post| %> <%= post.title %> <% end %><% end %>

Page 12: Lazy Loading and Object Proxying Shenangians

What now?

Page 13: Lazy Loading and Object Proxying Shenangians

class PostController < ApplicationController def index @posts = Post.all endend

@posts = Post.all is still evaluated ... and it’s expensive

Page 14: Lazy Loading and Object Proxying Shenangians

What about?

<% cache 'slow_posts' do %> <% Post.all.each do |post| %> <%= post.title %> <% end %><% end %>

Page 15: Lazy Loading and Object Proxying Shenangians

Separation of concerns?

Page 16: Lazy Loading and Object Proxying Shenangians

What about?

class PostController < ApplicationController def index unless fragment_exist? 'slow_posts' @posts = Post.all end endend

Page 17: Lazy Loading and Object Proxying Shenangians

Separation of concerns?

Page 18: Lazy Loading and Object Proxying Shenangians

What About?

class PostController < ApplicationController def index @posts = lazy_load { Post.all } endend

Page 19: Lazy Loading and Object Proxying Shenangians

Still not perfect ... but fuck it ... I’ve got a job

to get on with

Page 20: Lazy Loading and Object Proxying Shenangians

How?

Page 21: Lazy Loading and Object Proxying Shenangians

def lazy_load(&block) LazyLoader.new(&block) end

Page 22: Lazy Loading and Object Proxying Shenangians

class LazyLoader instance_methods.each { |m| undef_method m unless m =~ /^__/ } def initialize(&block) @_initializer = block end

protected # pass everything to _target def method_missing(method, *args, &block) _target.send method, *args, &block end

private # on first call will instantiate itself with _initializer block def _target @_target ||= @_initializer.call endend

Page 23: Lazy Loading and Object Proxying Shenangians

Gotchas:

Page 24: Lazy Loading and Object Proxying Shenangians

... or when I realised I wanted to be a

Smalltalk programmer

Page 25: Lazy Loading and Object Proxying Shenangians

<% if @post %> <%= @post.title %><% end %>

class PostController < ApplicationController def show @post = Post.find(params[:id]) endend

Page 26: Lazy Loading and Object Proxying Shenangians

<% cache 'slow_post' do %> <% if @post %> <%= @post.title %> <% end %><% end %>

class PostController < ApplicationController def show @post = lazy_load { Post.find(params[:id]) } endend

Page 27: Lazy Loading and Object Proxying Shenangians

NoMethodError:undefined method `title'

for nil:NilClass

Page 28: Lazy Loading and Object Proxying Shenangians

wtf?

Page 29: Lazy Loading and Object Proxying Shenangians

Ruby’s boolean operators don’t ask the objects for their truthyness

Word on the street is Smalltalk has that covered** I don’t know Smalltalk so hopefully I’m not full of shit right here

Page 30: Lazy Loading and Object Proxying Shenangians

a = lazy_load { nil } # this is finenil.nil? # => truea.nil? # => true # this is broken but.....# i can fix it by opening up NilClassa == nil # => truenil == a # => false # but what do i do about these?!!nil # => false!!a # => true if a puts "blah!"end # => "blah!"

Page 31: Lazy Loading and Object Proxying Shenangians

Two Solutions:

Page 32: Lazy Loading and Object Proxying Shenangians

<% cache 'slow_post' do %> <% unless @post.nil? %> <%= @post.title %> <% end %><% end %>

OR

Learn Smalltalk

Page 33: Lazy Loading and Object Proxying Shenangians

http://github.com/joho/lazy-loader

we’re pretty frickin rad, come work for us