Slide 1

Slide 1 text

here be dragons katrina owen @kytrinyx jumpstart lab

Slide 2

Slide 2 text

beezelbuB guile 93 havoc 87 speed 81 health 66 villain Armor invisible cloak

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

princess 0 dragon 000 000

Slide 6

Slide 6 text

princess 0 dragon 001 take that you filthy scum... 000

Slide 7

Slide 7 text

guile 12 havoc 68 speed 27 health 39 Bubba villain weapon sledge hammer

Slide 8

Slide 8 text

guile 2 havoc 0 speed 23 health 98 ALICE Villager magic item binoculars

Slide 9

Slide 9 text

+

Slide 10

Slide 10 text

Weight 9 length 21 speed 0 health 99 Nelson Baby Villager Magic Item Rattle

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

It is dark...

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

I tried to share by email but nothing happened.

Slide 15

Slide 15 text

HTTP/1.1 500 Internal Server Error

Slide 16

Slide 16 text

HTTP/1.1 500 Internal Server Error

Slide 17

Slide 17 text

request.form_input"=>#<StringIO:0x007fcbb690f540>, "rack.request.form_hash"=>{"emails"=>&quo [email protected]", "message"=>"", "name"=>"Katrina"}, uot;rack.request.form_vars"=>"[email protected]&message=&name=Katrina", uot;action_dispatch.request.path_parameters"=>{:action=>"share_by_mail_or_sms", :controller=>"greetings 94524"}, "action_controller.instance"=>#<GreetingsController:0x007fcbb7b2ca98 ...>, uot;action_dispatch.request.request_parameters"=>{"emails"=>"[email protected]", uot;message"=>"", "name"=>"Katrina"}, "rack.request.query_string"=>"&quot uot;rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request quot;emails"=>"[email protected]", "message"=>"", "name"=>"Katrina uot;action"=>"share_by_mail_or_sms", "controller"=>"greetings", "id"=>"34 uot;action_dispatch.request.accepts"=>[*/*], "action_dispatch.request.formats"=>[*/*]}, @fullpath="/tidbit are_by_email_or_sms", @filtered_parameters={"emails"=>"[email protected]", "message"=&g uot;name"=>"Katrina", "action"=>"share_by_mail_or_sms", "controller"=>"gr uot;id"=>"3494524"}, @method="POST">, @_env={"CONTENT_LENGTH"=>"57", uot;CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", uot;PATH_INFO"=>"/tidbits/123/share_by_email_or_sms", "QUERY_STRING"=>"", "REMOTE_ADDR 7.0.0.1", "REMOTE_HOST"=>"localhost", "REQUEST_METHOD"=>"POST", uot;REQUEST_URI"=>"http://gossip.dev/tidbits/123/share_by_email_or_sms", "SCRIPT_NAME"=>"", uot;SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000", "SERVER_PROTOCOL"=>&quot uot;SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20)", "HTTP_USER_AGENT"=>"curl/7.21.4 ( rwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5", "HTTP_HOST"=>"gossip.dev", "HTTP_ACCEPT"= uot;rack.version"=>[1, 1], "rack.input"=>#<StringIO:0x007fcbb690f540>, "rack.errors"=>#<I uot;rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, uot;rack.url_scheme"=>"http", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>&quo uot;action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>" 93f4924fec841d60443d392ff861b0da3ed5d024656a3afd79632dc52355a2aac249ccd32eba784fd61af2dbfc38fcb9ba5f1b6300696de3fc5cb14733198c" uot;action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{"session_id"=>"a7e33d9fc77a10921f uot;id"=>"bffb03fdf02a04a13e4c1ef5f2dad949208ae264c248e690"}, "rack.session.options"=>{:path=>&quo uot;, :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>"a7e33d9fc77a10921f460103c25e38fa& uot;action_dispatch.cookies"=>{}, "action_dispatch.request.unsigned_session_cookie"=> quot;session_id"=>"a7e33d9fc77a10921f460103c25e38fa"}, "action_dispatch.request.content_type"=>applic lencoded, "rack.request.form_input"=>#<StringIO:0x007fcbb690f540>, "rack.request.form_hash"=> quot;emails"=>"[email protected]", "message"=>"", "name"=>"Katrina uot;rack.request.form_vars"=>"[email protected]&message=&name=Katrina", uot;action_dispatch.request.path_parameters"=>{:action=>"share_by_mail_or_sms", :controller=>"greetings 94524"}, "action_controller.instance"=>#<GreetingsController:0x007fcbb7b2ca98 ...>, uot;action_dispatch.request.request_parameters"=>{"emails"=>"[email protected]", uot;message"=>"", "name"=>"Katrina"}, "rack.request.query_string"=>"&quot uot;rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request quot;emails"=>"[email protected]", "message"=>"", "name"=>"Katrina

Slide 18

Slide 18 text

curl -XPOST $URL \ --data "emails=$EMAILS&name=$NAME"

Slide 19

Slide 19 text

curl -XPOST $URL \ --data "emails=$EMAILS&name=$NAME" \ > out.html

Slide 20

Slide 20 text

curl -XPOST $URL \ --data "emails=$EMAILS&name=$NAME" \ > out.html open out.html

Slide 21

Slide 21 text

NoMethodError

Slide 22

Slide 22 text

class TidbitsController < ApplicationController # ~500 lines of code end

Slide 23

Slide 23 text

class TidbitsController < ApplicationController skip_before_filter :xyz, :only => [:share_by_email_or_sms] # ~500 lines of code end

Slide 24

Slide 24 text

curl -XPOST $URL \ --data "emails=$EMAILS&name=$NAME"

Slide 25

Slide 25 text

ENT"=>"curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5", quot;HTTP_HOST"=>"gossip.dev", "HTTP_ACCEPT"=>"*/*", "rack.version"=>[1, 1], quot;rack.input"=>#<StringIO:0x007fcbb6838ae0>, "rack.errors"=>#<IO:<STDERR>>, quot;rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, quot;rack.url_scheme"=>"http", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>&quo quot;action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>" a93f4924fec841d60443d392ff861b0da3ed5d024656a3afd79632dc52355a2aac249ccd32eba784fd61af2dbfc38fcb9ba5f1b6300696de3fc5cb14733198c" quot;action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{"session_id"=>"0c69cf043ced70e9ef quot;id"=>"058d52bacce4d0ba74276ce4561d46a65730347c78c11a94", "channel_id"=>176}, "rack.session.o :path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>" c69cf043ced70e9efd08cb1e7786890"}, "action_dispatch.cookies"=>{}, "action_dispatch.request.unsigned_session_co "session_id"=>"0c69cf043ced70e9efd08cb1e7786890"}, "action_dispatch.request.content_type"=>applic rlencoded, "rack.request.form_input"=>#<StringIO:0x007fcbb6838ae0>, "rack.request.form_hash"=> "emails"=>"[email protected]", "message"=>"", "name"=>"Katrina quot;rack.request.form_vars"=>"[email protected]&message=&name=Katrina", quot;action_dispatch.request.path_parameters"=>{:action=>"share_by_mail_or_sms", :controller=>"greetings 494524"}, "action_controller.instance"=>#<GreetingsController:0x007fcbb7a5bbf0 ...>, quot;action_dispatch.request.request_parameters"=>{"emails"=>"[email protected]", quot;message"=>"", "name"=>"Katrina"}, "rack.request.query_string"=>"&quot quot;rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request "emails"=>"[email protected]", "message"=>"", "name"=>"Katrina quot;action"=>"share_by_mail_or_sms", "controller"=>"greetings", "id"=>"34 quot;greeting"=>#<Greeting id: 3494524, title: "12 år 12.12.12", body: "Hipp hurra for jiinta vår! \r\nGrat ed ...", happens_on: "2012-12-12", created_at: "2012-12-10 08:53:43", updated_at: "2012-12-11 00:00:33& 76, display_mode_id: 5344, created_by: 9845, updated_by: 1, owner_name: "Leif Jørgen Larsen", age: 12, session_hash: nil, s 012-12-10 08:53:43", removed_at: nil, price: 0, kudos_count: 3, about: "Hanne Mari Larsen", uploaded_at: nil, claimed_ omment_count: 0, kind: "birthday", publish_on: nil, view_count: 22, image_uid: "image:apdm.gossip.oa.birthday$20121210 onfirmation_sent_at: "2012-12-10 08:53:43">, "sms_message"=>"Katrina vil at du skal se på en hilsen he is/personalia/greetings/3494524 Sendt fra www.gossip.dev"}, "action_dispatch.request.accepts"=>[*/*], quot;action_dispatch.request.formats"=>[*/*]}, @lookup_context=#<ActionView::LookupContext:0x007fcbb7a5aca0 @details_key=n details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=> :html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json], :locale=>[:"no-NB& B"]}, @skip_default_locale=false, @frozen_formats=false, @view_paths=[/Users/katrina/code/apps/gossip/app/views, /Users/katrina/ endor/plugins/papertime_client/app/views, /Users/katrina/code/apps/gossip/vendor/plugins/origo_client/app/views, /Users/katrina/code/ lugins/model_bars/app/views, /Users/katrina/code/apps/gossip/vendor/plugins/crummy/app/views, /Users/katrina/code/apps/gossip/vendor/ pdm_stationary_client/app/views, /Users/katrina/code/apps/gossip/vendor/plugins/acts_as_tsearch/app/views, /Users/katrina/code/apps/g ctive_merchant/app/views, /Users/katrina/.rvm/gems/ruby-1.9.3-p194@gossip/gems/kaminari-0.13.0/app/views]>, _action_name="share_by_mail_or_sms", @_response_body=nil, @crumbtrail=[{:title=>"Forsiden", :url=>"htt ww.gossip.dev"}, {:title=>"Folk i dag", :url=>"/vis/personalia/greetings"}], @_config={}, @current_cha 76, name: "Oppland Arbeiderblad", home_page: "http://www.gossip.dev", created_at: "2010-09-22 08:33:43"

Slide 26

Slide 26 text

ENT"=>"curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5", quot;HTTP_HOST"=>"gossip.dev", "HTTP_ACCEPT"=>"*/*", "rack.version"=>[1, 1], quot;rack.input"=>#<StringIO:0x007fcbb6838ae0>, "rack.errors"=>#<IO:<STDERR>>, quot;rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, quot;rack.url_scheme"=>"http", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>&quo quot;action_dispatch.parameter_filter"=>[:password], "action_dispatch.secret_token"=>" a93f4924fec841d60443d392ff861b0da3ed5d024656a3afd79632dc52355a2aac249ccd32eba784fd61af2dbfc38fcb9ba5f1b6300696de3fc5cb14733198c" quot;action_dispatch.remote_ip"=>127.0.0.1, "rack.session"=>{"session_id"=>"0c69cf043ced70e9ef quot;id"=>"058d52bacce4d0ba74276ce4561d46a65730347c78c11a94", "channel_id"=>176}, "rack.session.o :path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :id=>" c69cf043ced70e9efd08cb1e7786890"}, "action_dispatch.cookies"=>{}, "action_dispatch.request.unsigned_session_co "session_id"=>"0c69cf043ced70e9efd08cb1e7786890"}, "action_dispatch.request.content_type"=>applic rlencoded, "rack.request.form_input"=>#<StringIO:0x007fcbb6838ae0>, "rack.request.form_hash"=> "emails"=>"[email protected]", "message"=>"", "name"=>"Katrina quot;rack.request.form_vars"=>"[email protected]&message=&name=Katrina", quot;action_dispatch.request.path_parameters"=>{:action=>"share_by_mail_or_sms", :controller=>"greetings 494524"}, "action_controller.instance"=>#<GreetingsController:0x007fcbb7a5bbf0 ...>, quot;action_dispatch.request.request_parameters"=>{"emails"=>"[email protected]", quot;message"=>"", "name"=>"Katrina"}, "rack.request.query_string"=>"&quot quot;rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request "emails"=>"[email protected]", "message"=>"", "name"=>"Katrina quot;action"=>"share_by_mail_or_sms", "controller"=>"greetings", "id"=>"34 quot;greeting"=>#<Greeting id: 3494524, title: "12 år 12.12.12", body: "Hipp hurra for jiinta vår! \r\nGrat ed ...", happens_on: "2012-12-12", created_at: "2012-12-10 08:53:43", updated_at: "2012-12-11 00:00:33& 76, display_mode_id: 5344, created_by: 9845, updated_by: 1, owner_name: "Leif Jørgen Larsen", age: 12, session_hash: nil, s 012-12-10 08:53:43", removed_at: nil, price: 0, kudos_count: 3, about: "Hanne Mari Larsen", uploaded_at: nil, claimed_ omment_count: 0, kind: "birthday", publish_on: nil, view_count: 22, image_uid: "image:apdm.gossip.oa.birthday$20121210 onfirmation_sent_at: "2012-12-10 08:53:43">, "sms_message"=>"Katrina vil at du skal se på en hilsen he is/personalia/greetings/3494524 Sendt fra www.gossip.dev"}, "action_dispatch.request.accepts"=>[*/*], quot;action_dispatch.request.formats"=>[*/*]}, @lookup_context=#<ActionView::LookupContext:0x007fcbb7a5aca0 @details_key=n details={:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=> :html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json], :locale=>[:"no-NB& B"]}, @skip_default_locale=false, @frozen_formats=false, @view_paths=[/Users/katrina/code/apps/gossip/app/views, /Users/katrina/ endor/plugins/papertime_client/app/views, /Users/katrina/code/apps/gossip/vendor/plugins/origo_client/app/views, /Users/katrina/code/ lugins/model_bars/app/views, /Users/katrina/code/apps/gossip/vendor/plugins/crummy/app/views, /Users/katrina/code/apps/gossip/vendor/ pdm_stationary_client/app/views, /Users/katrina/code/apps/gossip/vendor/plugins/acts_as_tsearch/app/views, /Users/katrina/code/apps/g ctive_merchant/app/views, /Users/katrina/.rvm/gems/ruby-1.9.3-p194@gossip/gems/kaminari-0.13.0/app/views]>, _action_name="share_by_mail_or_sms", @_response_body=nil, @crumbtrail=[{:title=>"Forsiden", :url=>"htt ww.gossip.dev"}, {:title=>"Folk i dag", :url=>"/vis/personalia/greetings"}], @_config={}, @current_cha 76, name: "Oppland Arbeiderblad", home_page: "http://www.gossip.dev", created_at: "2010-09-22 08:33:43"

Slide 27

Slide 27 text

I18n::MissingInterpolationArgument

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

controller

Slide 30

Slide 30 text

controller share_by_email_or_sms

Slide 31

Slide 31 text

controller share_by_email_or_sms

Slide 32

Slide 32 text

module share_by_email_or_sms

Slide 33

Slide 33 text

module share_by_email_or_sms send_to_recipients

Slide 34

Slide 34 text

share_by_email_or_sms send_to_recipients send_to_email module

Slide 35

Slide 35 text

share_by_email_or_sms send_to_recipients send_to_email module

Slide 36

Slide 36 text

mailer share_by_email_or_sms send_to_recipients send_to_email

Slide 37

Slide 37 text

mailer share_by_email_or_sms send_to_recipients send_to_email tidbit_tip

Slide 38

Slide 38 text

mailer share_by_email_or_sms send_to_recipients send_to_email tidbit_tip

Slide 39

Slide 39 text

template share_by_email_or_sms send_to_recipients send_to_email tidbit_tip tidbit_tip.text.erb

Slide 40

Slide 40 text

template share_by_email_or_sms send_to_recipients send_to_email tidbit_tip tidbit_tip.text.erb

Slide 41

Slide 41 text

i18n share_by_email_or_sms send_to_recipients send_to_email tidbit_tip tidbit_tip.text.erb

Slide 42

Slide 42 text

i18n share_by_email_or_sms send_to_recipients send_to_email tidbit_tip tidbit_tip.text.erb I18n.translate

Slide 43

Slide 43 text

i18n missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given)

Slide 44

Slide 44 text

Error Message missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given)

Slide 45

Slide 45 text

missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given) Error Message

Slide 46

Slide 46 text

missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given) Error Message

Slide 47

Slide 47 text

missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given) Error Message

Slide 48

Slide 48 text

missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given) Error Message

Slide 49

Slide 49 text

missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given) Error Message

Slide 50

Slide 50 text

missing interpolation argument in "%{tidbit_sender} has congratulated %{tidbit_about} in %{publication}. %{tip_sender} wants you to take a look." ( { :tip_sender=>"Katrina", :tidbit_about=>"Eve Smith", :publication=>"The Village Rag" } given) Error Message

Slide 51

Slide 51 text

error message <%= t("emails.tip_mail.introduction") % { :tip_sender => @tip_sender, :tidbit_about => @tidbit.about, :publication => @tidbit.publication } %>

Slide 52

Slide 52 text

template <%= t("emails.tip_mail.introduction") % { :tip_sender => @tip_sender, :tidbit_about => @tidbit.about, :publication => @tidbit.publication } %>

Slide 53

Slide 53 text

<%= t("emails.tip_mail.introduction") % { :tip_sender => @tip_sender, :tidbit_about => @tidbit.about, :publication => @tidbit.publication :tidbit_sender => @tidbit.from } %> template

Slide 54

Slide 54 text

curl -XPOST $URL \ --data "emails=$EMAILS&name=$NAME"

Slide 55

Slide 55 text

HTTP/1.1 200 OK { "success": ["[email protected]"] }

Slide 56

Slide 56 text

HTTP/1.1 200 OK { "success": ["[email protected]"] } 1up

Slide 57

Slide 57 text

1 new message HTTP/1.1 200 OK { "success": ["[email protected]"] }

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

All your bugs are belong to us...

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

This could be dangerous...

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

class TidbitsController < ApplicationController # ~500 lines of code end

Slide 65

Slide 65 text

controller class TidbitsController < ApplicationController # ~500 lines of code end

Slide 66

Slide 66 text

class TidbitsController < ApplicationController def share_by_email_or_sms # ... end end controller

Slide 67

Slide 67 text

controller def share_by_email_or_sms # ... tinyurl = Tinyurl.shorten(tidbit.url) # ... end

Slide 68

Slide 68 text

module Tinyurl # ~75 lines of code end controller

Slide 69

Slide 69 text

module Tinyurl # ~75 lines of code end module

Slide 70

Slide 70 text

# Base exception class module

Slide 71

Slide 71 text

# Base exception class class TinyurlException < Exception end module

Slide 72

Slide 72 text

# Exception class module

Slide 73

Slide 73 text

# Exception class class InvalidUrlException < TinyurlException end module

Slide 74

Slide 74 text

# Get a nice one from the API module

Slide 75

Slide 75 text

# Get a nice one from the API def self.lookup_tiny_url(url) # 16 LOC end module

Slide 76

Slide 76 text

# If we sohuld ask the API... module

Slide 77

Slide 77 text

# If we sohuld ask the API... def self.should_lookup_tiny_url? # 7 LOC end module

Slide 78

Slide 78 text

def self.lookup_tiny_url(url) # ... uri = URI.parse(endpoint) Net::HTTP.start(uri.host, uri.port) do |api| api.get("#{uri.path}?#{uri.query}") end # ... end def self.endpoint "http://is.gd/create.php" end module

Slide 79

Slide 79 text

def self.should_lookup_tiny_url? return false if cached? # ... end module

Slide 80

Slide 80 text

def self.should_lookup_tiny_url? return false if cached? case env when "production" then return true when "staging" then return true else return false end false end module

Slide 81

Slide 81 text

def self.should_lookup_tiny_url? return false if cached? case env when "production" then return true when "staging" then return true else return false end false end module

Slide 82

Slide 82 text

module def self.should_lookup_tiny_url? return false if cached? case env when "production" then return true when "staging" then return true else return false end false end

Slide 83

Slide 83 text

module def self.should_lookup_tiny_url? return false if cached? case env when "production" then return true when "staging" then return true else return false end false end

Slide 84

Slide 84 text

module def self.should_lookup_tiny_url? return false if cached? ["production", "staging"].include? env end

Slide 85

Slide 85 text

@@lookup_tiny_urls = {} def self.shorten(url) @url = url # ... end def self.cached? !!@@lookup_tiny_urls[@url] end module

Slide 86

Slide 86 text

!!@@lookup_tiny_urls[@url] module

Slide 87

Slide 87 text

No content

Slide 88

Slide 88 text

This could be dangerous...

Slide 89

Slide 89 text

module module Tinyurl # ~75 lines of code end

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

Take that you filthy scum...

Slide 92

Slide 92 text

xp 000

Slide 93

Slide 93 text

xp +4 000

Slide 94

Slide 94 text

xp 004

Slide 95

Slide 95 text

xp 004 +1

Slide 96

Slide 96 text

xp 005

Slide 97

Slide 97 text

xp +2 005

Slide 98

Slide 98 text

xp 007

Slide 99

Slide 99 text

xp 007 +2

Slide 100

Slide 100 text

xp 009

Slide 101

Slide 101 text

xp 009 +4

Slide 102

Slide 102 text

xp 013

Slide 103

Slide 103 text

xp 013 +2

Slide 104

Slide 104 text

xp 015

Slide 105

Slide 105 text

xp 015 +1

Slide 106

Slide 106 text

xp 016

Slide 107

Slide 107 text

xp 016 +8

Slide 108

Slide 108 text

xp 024

Slide 109

Slide 109 text

xp 024 +16

Slide 110

Slide 110 text

xp 040

Slide 111

Slide 111 text

xp 040 +32

Slide 112

Slide 112 text

xp 062 achievement unlocked

Slide 113

Slide 113 text

xp class TidbitsController < ApplicationController def share_by_email_or_sms # ~50 LOC end # ~450 LOC end 062

Slide 114

Slide 114 text

xp class TidbitsController < ApplicationController def share_by_email_or_sms # ~50 LOC end # ~450 LOC end 062 controller

Slide 115

Slide 115 text

xp 062 def share_by_email_or_sms # ... unless invalid_name # ... else # ... end end controller

Slide 116

Slide 116 text

xp 064 def share_by_email_or_sms # ... unless invalid_name # ... else # ... end end controller

Slide 117

Slide 117 text

xp def share_by_email_or_sms # ... unless invalid_name # ... else # ... end end 064 controller

Slide 118

Slide 118 text

xp 064 controller def share_by_email_or_sms # ... unless invalid_name # ... else # ... end end

Slide 119

Slide 119 text

xp 066 controller def share_by_email_or_sms # ... unless invalid_name # ... else # ... end end

Slide 120

Slide 120 text

xp 066 name = params[:name] if name && name.length > 40 invalid_name = true else # ... end controller

Slide 121

Slide 121 text

xp 070 name = params[:name] if name && name.length > 40 invalid_name = true else # ... end controller

Slide 122

Slide 122 text

xp NAME=$(ruby -e "40.times { print 'x' }") curl -XPOST $URL \ --data "emails=$EMAILS&name=$NAME" 070

Slide 123

Slide 123 text

xp HTTP/1.1 400 Bad Request { "error": "Invalid name." } 070

Slide 124

Slide 124 text

HTTP/1.1 400 Bad Request { "error": "Invalid name." }

Slide 125

Slide 125 text

HTTP/1.1 400 Bad Request { "error": "Invalid name." } 1 new message

Slide 126

Slide 126 text

xp 070 +64

Slide 127

Slide 127 text

xp 134

Slide 128

Slide 128 text

xp if name && name.length > 40 invalid_name = true end controller 134

Slide 129

Slide 129 text

xp if name && name.length > 40 # ... end Gossip::Sharing.send_to_recipients(params) controller 134

Slide 130

Slide 130 text

xp controller if name && name.length > 40 # ... end Gossip::Sharing.send_to_recipients(params) unless invalid_name # ... else halt 400, {error: "Invalid name."}.to_json end 134

Slide 131

Slide 131 text

No content

Slide 132

Slide 132 text

It is dark...

Slide 133

Slide 133 text

xp name = params[:name] if name && name.length > 40 invalid_name = true end controller 134

Slide 134

Slide 134 text

xp curl -XPOST $URL \ --data "emails=$EMAILS" 134

Slide 135

Slide 135 text

xp 134 HTTP/1.1 400 Bad Request { "error": }

Slide 136

Slide 136 text

xp 134 HTTP/1.1 400 Bad Request { "error": "They have already been told." }

Slide 137

Slide 137 text

xp HTTP/1.1 400 Bad Request { "error": "They have already been told." } 142

Slide 138

Slide 138 text

No content

Slide 139

Slide 139 text

This could be dangerous...

Slide 140

Slide 140 text

xp module Sharing # ~75 lines of code end 142

Slide 141

Slide 141 text

xp module module Sharing # ~75 lines of code end 142

Slide 142

Slide 142 text

xp module module Sharing def self.send_to_recipients(params) # ... end end 142

Slide 143

Slide 143 text

xp # Sends a params[:message] to a set of # params[:email_recipients] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end module 142

Slide 144

Slide 144 text

xp # Sends a params[:message] to a set of # params[:email_recipients] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end module 142

Slide 145

Slide 145 text

xp 142 # Sends a params[:sms] to a set of # params[:email_recipients] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end module

Slide 146

Slide 146 text

xp 144 # Sends a params[:sms] to a set of # params[:email_recipients] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end module

Slide 147

Slide 147 text

xp # Sends a params[:sms] to a set of # params[:email_recipients] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end 144 module

Slide 148

Slide 148 text

xp 144 # Sends a params[:sms] to a set of # params[:email] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end module

Slide 149

Slide 149 text

xp 146 # Sends a params[:sms] to a set of # params[:email] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end module

Slide 150

Slide 150 text

xp # Sends a params[:sms] to a set of # params[:email] and # params[:sms_recipients] def self.send_to_recipients(params) # ... end 146 module

Slide 151

Slide 151 text

xp 146 # Sends a params[:sms] to a set of # params[:email] and # params[:numbers] def self.send_to_recipients(params) # ... end module

Slide 152

Slide 152 text

xp 148 # Sends a params[:sms] to a set of # params[:email] and # params[:numbers] def self.send_to_recipients(params) # ... end module

Slide 153

Slide 153 text

xp # Sends a params[:sms] to a set of # params[:email] and params[:numbers] def self.send_to_recipients(params) # ... end 148 module

Slide 154

Slide 154 text

xp 148 # Sends a params[:sms] to a set of # params[:email] and params[:numbers] def self.send_to_recipients(params) # ... end module

Slide 155

Slide 155 text

xp 150 # Sends a params[:sms] to a set of # params[:email] and params[:numbers] def self.send_to_recipients(params) # ... end module

Slide 156

Slide 156 text

xp # Sends params[:sms] to params[:numbers] # and a templated email to params[:email] def self.send_to_recipients(params) # ... end module 150

Slide 157

Slide 157 text

xp def self.send_to_recipients(params) # ... end module 150

Slide 158

Slide 158 text

xp module 150 if params[:message] params[:sms].strip! params[:sms].squeeze!(" ") end

Slide 159

Slide 159 text

xp 150 module if params[:message] params[:sms].strip! params[:sms].squeeze!(" ") end

Slide 160

Slide 160 text

xp 151 module if params[:message] params[:sms].strip! params[:sms].squeeze!(" ") end

Slide 161

Slide 161 text

xp 151 params[:name].strip! params[:name].squeeze!(" ") module

Slide 162

Slide 162 text

xp 153 params[:name].strip! params[:name].squeeze!(" ") module

Slide 163

Slide 163 text

xp 153 params[:name].strip! params[:name].squeeze!(" ") if params[:name].length > 41 return false end module

Slide 164

Slide 164 text

xp 161 params[:name].strip! params[:name].squeeze!(" ") if params[:name].length > 41 return false end module

Slide 165

Slide 165 text

xp recipients = [emails, phone_numbers].flatten recipients.each do |r| # lots of stuff unless stuff? if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i send_to_email(r, params) elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ send_to_sms(r, params) end # more stuff end end module 161

Slide 166

Slide 166 text

xp 161 +128

Slide 167

Slide 167 text

xp 289 high score

Slide 168

Slide 168 text

xp recipients = [emails, phone_numbers].flatten module 289

Slide 169

Slide 169 text

xp recipients = [emails, phone_numbers].flatten recipients.each do |r| end module 289

Slide 170

Slide 170 text

xp recipients = [emails, phone_numbers].flatten recipients.each do |r| if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ end end module 289

Slide 171

Slide 171 text

xp recipients = [emails, phone_numbers].flatten recipients.each do |r| if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i send_to_email(r, params) elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ end end module 289

Slide 172

Slide 172 text

xp recipients = [emails, phone_numbers].flatten recipients.each do |r| if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i send_to_email(r, params) elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ send_to_sms(r, params) end end module 289

Slide 173

Slide 173 text

xp if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i send_to_email(r, params) elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ send_to_sms(r, params) end module 289

Slide 174

Slide 174 text

xp module # Send email def self.send_to_email(address, params) # ... end 289

Slide 175

Slide 175 text

xp module def self.send_to_email(address, params) if tidbit.created_by.email Mailer.tidbit_tip(address, params).deliver end true end 289

Slide 176

Slide 176 text

xp module Alice has a baby and posts a picture. Bob tells Charlie about it Bob provides Charlie’s email 289

Slide 177

Slide 177 text

xp Story Alice has a baby and posts a picture. Bob tells Charlie about it Bob provides Charlie’s email 289

Slide 178

Slide 178 text

xp Story def self.send_to_email(address, params) if tidbit.created_by.email Mailer.tidbit_tip(address, params).deliver end true end 289

Slide 179

Slide 179 text

xp Module def self.send_to_email(address, params) if tidbit.created_by.email Mailer.tidbit_tip(address, params).deliver end true end 289

Slide 180

Slide 180 text

xp def self.send_to_email(address, params) if tidbit.created_by.email Mailer.tidbit_tip(address, params).deliver end true end module 289

Slide 181

Slide 181 text

xp 289 +16

Slide 182

Slide 182 text

xp 305

Slide 183

Slide 183 text

xp def self.send_to_email(address, params) if tidbit.created_by.email Mailer.tidbit_tip(address, params).deliver end true end module 305

Slide 184

Slide 184 text

xp recipients = [emails, phone_numbers].flatten recipients.each do |r| # lots of stuff unless stuff? if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i send_to_email(r, params) elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ send_to_sms(r, params) end # more stuff end end module 161

Slide 185

Slide 185 text

xp sent = [] recipients = [emails, phone_numbers].flatten recipients.each do |r| # lots of stuff unless stuff? if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i if send_to_email(r, params) sent << r end elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ if send_to_sms(r, params) sent << r end end # more stuff end end sent module 161

Slide 186

Slide 186 text

xp def self.send_to_email(address, params) if tidbit.created_by.email Mailer.tidbit_tip(address, params).deliver end true end module 305

Slide 187

Slide 187 text

xp if r =~ /^([^@\s,]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i send_to_email(r, params) elsif r =~ /^\s*\+?[0-9[:space:]]+\s*$/ send_to_sms(r, params) end module 305

Slide 188

Slide 188 text

xp # Send SMS def self.send_to_sms(number, params) # ... end module 305

Slide 189

Slide 189 text

xp # Send SMS def self.send_to_sms(number, params) # TODO: Send SMS here end module 305

Slide 190

Slide 190 text

xp 305 +256

Slide 191

Slide 191 text

xp 561 high score

Slide 192

Slide 192 text

No content

Slide 193

Slide 193 text

No content

Slide 194

Slide 194 text

Fundamental Attribution Error

Slide 195

Slide 195 text

No content

Slide 196

Slide 196 text

TODO: Send sms here

Slide 197

Slide 197 text

No content

Slide 198

Slide 198 text

PLAYER 1 PLAYER 2

Slide 199

Slide 199 text

PLAYER 1 PLAYER 2

Slide 200

Slide 200 text

PLAYER 1 PLAYER 2 cooperate cooperate

Slide 201

Slide 201 text

PLAYER 1 PLAYER 2 cooperate cooperate 3 3

Slide 202

Slide 202 text

No content

Slide 203

Slide 203 text

Reward

Slide 204

Slide 204 text

PLAYER 1 PLAYER 2

Slide 205

Slide 205 text

PLAYER 1 PLAYER 2 Defect Defect

Slide 206

Slide 206 text

PLAYER 1 PLAYER 2 Defect Defect 1 1

Slide 207

Slide 207 text

No content

Slide 208

Slide 208 text

Punishment

Slide 209

Slide 209 text

PLAYER 1 PLAYER 2

Slide 210

Slide 210 text

PLAYER 1 PLAYER 2 Cooperate

Slide 211

Slide 211 text

PLAYER 1 PLAYER 2 Cooperate Defect

Slide 212

Slide 212 text

PLAYER 1 PLAYER 2 Cooperate Defect 5

Slide 213

Slide 213 text

No content

Slide 214

Slide 214 text

Temptation

Slide 215

Slide 215 text

PLAYER 1 PLAYER 2 Cooperate Defect 5

Slide 216

Slide 216 text

PLAYER 1 PLAYER 2 Cooperate Defect 0 5

Slide 217

Slide 217 text

No content

Slide 218

Slide 218 text

Sucker’s Payoff

Slide 219

Slide 219 text

No content

Slide 220

Slide 220 text

Cooperate

Slide 221

Slide 221 text

No content

Slide 222

Slide 222 text

Defect

Slide 223

Slide 223 text

PLAYER 1 PLAYER 2

Slide 224

Slide 224 text

PLAYER 1 PLAYER 2 Defect

Slide 225

Slide 225 text

PLAYER 1 PLAYER 2 Defect Defect

Slide 226

Slide 226 text

PLAYER 1 PLAYER 2 Defect Defect 1 1

Slide 227

Slide 227 text

PLAYER 1 PLAYER 2

Slide 228

Slide 228 text

PLAYER 1 PLAYER 2 cooperate

Slide 229

Slide 229 text

PLAYER 1 PLAYER 2 Defect cooperate

Slide 230

Slide 230 text

PLAYER 1 PLAYER 2 Defect cooperate 5

Slide 231

Slide 231 text

PLAYER 1 PLAYER 2 Defect cooperate 5 0

Slide 232

Slide 232 text

No content

Slide 233

Slide 233 text

Always Defect

Slide 234

Slide 234 text

No content

Slide 235

Slide 235 text

No content

Slide 236

Slide 236 text

Cooperate as long as possible

Slide 237

Slide 237 text

No content

Slide 238

Slide 238 text

No content

Slide 239

Slide 239 text

The Evolution of Cooperation

Slide 240

Slide 240 text

No content

Slide 241

Slide 241 text

No content

Slide 242

Slide 242 text

Reward

Slide 243

Slide 243 text

No content

Slide 244

Slide 244 text

Temptation

Slide 245

Slide 245 text

No content

Slide 246

Slide 246 text

Sucker’s Payoff

Slide 247

Slide 247 text

No content

Slide 248

Slide 248 text

Punishment

Slide 249

Slide 249 text

No content

Slide 250

Slide 250 text

No content

Slide 251

Slide 251 text

Thank You

Slide 252

Slide 252 text

Credits Source Code Anonymous Pixel Bug Illustrations Persa Zula The Evolution of Cooperation Robert Axelrod The Prisoner’s Dilemma Game Theory 101

Slide 253

Slide 253 text

katrina owen @kytrinyx jumpstart lab