Lazy Loading and Object Proxying Shenangians

33
Lazy Loading ..and object proxying shenanigans
  • date post

    12-Sep-2014
  • Category

    Technology

  • view

    1.493
  • download

    2

description

A presentation delivered to the Ruby on Rails Oceania Melbourne group's October meet up.Covers how to cleaning organise controller code with object proxying to play well with fragment caching in the views

Transcript of Lazy Loading and Object Proxying Shenangians

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