Worst. Ideas. Evar.
      TODO: Subtitle
Scope

• We’re not here to trash on other ppl’s
  projects.

• Not a worst practices show and tell.
• Well engineered, but horrible ideas.
Bios
• We both work at AT&T Interactive.
• We've done ruby for a long time.
• Blah blah blah boring...
Bios
• We both work at AT&T Interactive.
• We've done ruby for a long time.
• Blah blah blah boring...       NOTE:
                              none of this
                             presentation or
                              software was
                         supported, sanctioned,
                           endorsed, or even
                            tolerated by our
                               employer.
AT&T Interactive:
Please don't fire us!
Aaron
• Likes kittens, ponies, and vim.
• Is totally in love with his mustache.
• Prefers to write C code over ruby. Think about it:
 • nokogiri? C
 • johnson? C
 • never_say_die? C
 • psych? C
 • phuby? C
 • nfc? C
 • earworm? C
 • qrtools? C
Ryan Davis
• Likes kittens, ponies, and emacs.
• Is totally in love with his ponytail.
• Wishes Sting never left the Police.
• Fears nothing except:
 • mushrooms
 • asparagus
• Hates it when I sing.
• Same colors, everyday.           Redacted
What is a Bad Idea?
Meta: These Slides
Not These Slides
These Slides
Field Guide
     Spotting bad ideas in the wild



• Well engineered & tested.
• Useless-ish.
• Poe’s Law.
• Spiral nature.
W
        Field Guide                   U
     Spotting bad ideas in the wild
                                      P
                                      S

• Well engineered & tested.
• Useless-ish.
• Poe’s Law.
• Spiral nature.
W
Well Engineered & Tested                U
                                        P
                                        S


• Bad Ideas != Bad Code.
• Good Code + Tests > Horrible Idea.
• Be wary of the well tested project!
W
       Useless-ish                   U
                                     P
                                     S


• They must be useless… ish.
• They should do something.
• Just not anything you need/want.
W
                 Poe’s Law                                      U
                                                                P
"Without a winking smiley or other blatant display of           S
humour, it is impossible to create a parody of
fundamentalism that someone won't mistake for the real
thing," [1]

"…it is hard to tell parodies of fundamentalism from the
real thing, since they both seem equally insane.
Conversely, real fundamentalism can easily be mistaken
for a parody of fundamentalism." [2]

                          [1] http://en.wikipedia.org/wiki/Poe's_law
                         [2] http://rationalwiki.com/wiki/Poe's_Law
                   [awesome] http://conservapedia.com/Poe's_law
W
               Poe’s Law                             U
                                                     P
                                                     S
•   From high level, they can sound perfectly
    reasonable.

•   Solution looking for a problem.

    •   They don't solve any immediate problems at
        hand. They generate them.

•   Everyone always ignores that guy in the corner
    asking “Really???”. I mean, c'mon… what does
    he know?
W
     Spiral Nature                      U
                                        P
                                        S


• The best part of Bad Ideas is that
  they build upon one another.

• Hopefully with cyclic dependencies.
Hypothetical Examples
       (Read: We haven't finished them… yet)


• XML multi file format (a la java's jar
  format)

• DRB over RFID
• DRB over QR/Bar Code via webcams
• Assembly optimized web pages
• FFI
Yoda
Yoda

• Bad ideas can be high level.
• Test frameworks are the new IRC
  bot!

• Yoda defines a spec language in the
  direction we think they should be.
Bowling.yoda {
 "score 0 for gutter game".it_will {
   bowling = Bowling.new
   20.times { bowling.hit(0) }

        bowling.score 0.it_is?
        bowling.score 42.it_is_not!
    }
}
./lib/yoda.rb:5:in `fail_me': Fail me you did: 1 != 0
(Yoda::FailMe)

 from ./lib/yoda.rb:19:in `matches'

 from (eval):5:in `score'

 from example.rb:19

 from ./lib/yoda.rb:45:in `it_will'

 from example.rb:15

 from ./lib/yoda.rb:63:in `yoda'

 from example.rb:14
W
So Simple It Can't Break                  U
                                          P
                                          S

• 65 lines of Jedi Master Ruby.
• 3 conditionals, 1 loop.
• Flogs to 41.1, avg 4.1 / method. LOW!
• How can you go wrong?
W
    Useless, am I?                  U
                                    P
                                    S



• Not exactly very expressive.
• Then again, doesn't need to be.
W
Poe's got nothin' on Yoda           U
                                    P
                                    S



• Really? Another test framework?
• Really?
W
The Force is Everywhere        U
                               P
                               S



• It is a test framework…
• You can use it everywhere!
Wilson
Ruby is SLOW
C is not!
But, why write in C?
When you can write
  in Assembly?
Wilson
•   Bad ideas can be very
    low level.

•   Generates x86
    machine code via a
    "natural" feeling ruby
    DSL.

•   Named after the
    very metal Wilson
    Bilkovich.
Inline-C
class Counter
 inline do |builder|
   builder.c "
    long cee(int n) {
      long i;
      for (i = 0;i<n+1;i++) {};
      return i;
    }"
 end
end
Wilsasm
class Counter
 defasm :asm2, :n do
   eax.xor eax

  edx.mov arg(0)
  from_ruby edx
  edx.inc

  count = self.label
  eax.inc
  eax.cmp edx
  jnz count

  to_ruby eax
 end
end
Wilsasm
class Counter
 defasm :asm2, :n do
   eax.xor eax

  edx.mov arg(0)
  from_ruby edx
  edx.inc

  count = self.label
  eax.inc
  eax.cmp edx
  jnz count

  to_ruby eax
 end
end
Benchmarks!
% rm -r ~/.ruby_inline; ./bench.rb 1_000_000 1_000
# of iterations = 1000000
$n = 1000
                  user   system     total  real
null_time          0.120000 0.000000 0.120000 ( 0.122507)
cee_nil           0.280000 0.000000 0.280000 ( 0.279552)
asm_nil            0.280000 0.000000 0.280000 ( 0.275498)
ruby_nil          0.370000 0.000000 0.370000 ( 0.372142)
cee               0.830000 0.010000 0.840000 ( 0.837607)
asm2               0.830000 0.000000 0.830000
( 0.839430)
asm               3.520000 0.000000 3.520000 ( 3.542521)
ruby             98.970000 0.430000 99.400000
(101.903256)
W
      Whip-Smart                      U
                                      P
                                      S
• Generates machine code directly:
 • No dependencies.
 • No external resources.
 • Parses the 60 page x86 spec into
   instructions and their opcodes.
W
             "Uses"                   U
                                      P
                                      S

• Good at writing really fast code.
• And crashing. Fast.
• I don't think anyone uses this.
 • (I hope not)
W
Poe Man's Dispatch                      U
                                        P
                                        S

• The original intent was to write a
  pure ruby method dispatch function.

 • But that is hard.
  • And we got laid off of Rubinius.
W
            Spiral?                     U
                                        P
                                        S


• It was intended to be the core of a
  new ruby implementation.

• How much more spiral do you want?
Wank
Wank


• Human Readable Marshal Format
Why Wank?
Marshal data is too hard
             to read



Marshal.dump nil # => "004b0"



                        Unreadable,
                      therefore useless
YAML is too hard to read




YAML.dump nil # => "--- n"



                        Unreadable,
                      therefore useless
Websites are
 Readable
Exhibit A
W
           U
           P
           S


The Guts
W
       Language           U
                          P
     Dependencies         S


• Ruby (of course)
• YAML (psych)
• XML / HTML (nokogiri)
W
           Data is a Tree                 U
                                          P
                                          S



o={
  :foo => [1,2,3,4],
  'mom' => Struct.new(:data).new('bar')
}
W
    Ruby Data Graph                     U
                                        P
                  o                     S


           :foo           mom




1      2    3         4         :data




                                bar
W
HTML data graph      U
                     P
        html         S

        body




        table




         tr




   td    td     td
W
              U
              P
              S

Translation
W
                 U
                 P
                 S

HTML data is a
subset of Ruby
W
                     U
                     P
                     S


YAML to the rescue
W
   YAML Representation   U
                         P
                         S

---
:foo:
-1
-2
-3
-4
mom: !ruby/struct
  :data: bar
W
             Ruby => YAML AST                                                                      U
                                                                                                   P
                                                                                                   S
                                                 Stream




                                             Document




                                             Mapping




                Scalar       :foo     Sequence       Scalar        mom      Mapping




Scalar   1    Scalar     2          Scalar   3            Scalar     4   Scalar   :data   Scalar   bar
W
     YAML AST => HTML                                                             U
                                                                                  P
                                                                                  S
                                         HTML




                                         BODY




                                          DL




              DT       :foo    DD / OL         DT        mom    DD / DL




LI   1   LI        2          LI     3              LI     4   DT    :data   DD   bar
W
               Sample Use                U
                                         P
                                         S


o={
  :foo => [1,2,3,4],
  'bar' => Struct.new(:foo).new('bar')
}

Wank::HTML::Marshal.dump(o)
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
                                                                          W
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
                                                                          U
 <body>
  <dl>
                                                                          P
   <dt>bar</dt>
   <dd>
                                                                          S
    <dl class="!ruby/struct ">
      <dt>foo</dt>
      <dd>bar</dd>
    </dl>
   </dd>
   <dt>:foo</dt>
   <dd>
    <ol>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ol>
   </dd>
  </dl>
 </body>
</html>
W
U
P
S
W
       Wank in Style!    U
                         P
                         S
dl {
  border: solid green;
}

dt:after {
  content: " => ";
}

ol {
  border: solid blue;
}
W
U
P
S
W
 The Circle of       U
                     P
   Terrible          S

       Ruby




YAML          YAML




       HTML
W
Wank over DRb   U
                P
                S


     HTML!
W
      Wank over DRb                  U
                                     P
                                     S




DRb::Marshal = Wank::HTML::Marshal
W
          Wank on Rack        U
                              P
                              S
module Rack
 class Wank
  include Wank::HTML

  def call env
    [
      200,
      {},
      Marshal.dump("hello")
    ]
  end
 end
end
W
        Wank on Rails                   U
                                        P
                                        S

class WankController
 def show
   @wanker = Wanker.find(params[:id])
   render :text =>
    Wank::HTML::Marshal.dump(@wanker)
 end
end
W
               U
               P
               S

You can Wank
 Anywhere!
Never Say Die
Never Say Die


• Rescue from segfaults
• Create segfaults
libsigsegv
• pageable virtual memory
• memory mapped access to databases
• generational garbage collectors
• stack overflow handlers
• distributed shared memory
libsigsegv
• pageable virtual memory


HUH?
• memory mapped access to databases
• generational garbage collectors
• stack overflow handlers
• distributed shared memory
Trap INT


trap(“INT”) do
  puts "haha! no!"
end
Trap SEGV

begin

 ... # something dangerous

rescue NeverSayDie

 ... # Fix your memory!

end
W
               U
               P
               S


Fully Tested
W
                    U
                    P
                    S


NeverSayDie::segv
W
                                 U
                                 P
begin                            S
 NeverSayDie.segv

rescue NeverSayDie => maverick

 return maverick     # =>

end
W
                                 U
                                 P
begin                            S
 NeverSayDie.segv

rescue NeverSayDie => maverick

 return maverick     # =>

end
W
Uselessish   U
             P
             S
W
        Uselessish              U
                                P
                                S



• If you think you need this…
W
        Uselessish              U
                                P
                                S



• If you think you need this…
 • well, you probably do.
W
                Poe's Law                  U
                                           P
                                           S
begin
 asm :thuper_optimized do
  eax.mov 0
  ecx.mov 10
  count = self.label
  eax.add 1
  count.loop

   to_ruby eax
 end
rescue NeverSayDie # run the slow one :(
 1.upto(10) do; end
end            # really??
W
    Never Say Die, on Rails   U
                              P
                              S

class SegvController < ...
 def index
   ...
 rescue NeverSayDie
   ... # Yay! More uptime!
 end
end
Phuby
Because Rails
programmers are
  secretly PHP
  programmers
Hire PHP
Programmers!
They're cheap!
Phuby


• PHP embedded in Ruby
Source of Bad Ideas

• Ryan came up with the idea of Phuby.
• Aaron implemented phuby.
• Ryan is counting this as a win x 2.
W
                  U
                  P
                  S


Well Engineered
Ruby var => PHP
   Ruby           C          PHP

                   Proxy
Weak Ref Table               PHP
                 (runtime)




    Ruby
Ruby var => PHP
   Ruby           C          PHP

                   Proxy
Weak Ref Table               PHP
                 (runtime)




    Ruby
Weak Ref Table


• PHP object memory location (INT)
• VALUE
PHP calling Ruby
   Ruby            C          PHP

                    Proxy
Weak Ref Table                PHP
                  (runtime)




    Ruby
PHP calling Ruby
   Ruby            C          PHP

                    Proxy
Weak Ref Table                PHP
                  (runtime)




    Ruby
Ruby calling PHP
Ruby           C          PHP

                Proxy
Ruby                      PHP
              (runtime)
Ruby calling PHP
Ruby           C          PHP

                Proxy
Ruby                      PHP
              (runtime)




               Proxy
              (object)
W
               Ruby.PHP()                    U
                                             P
                                             S



Phuby::Runtime.php do |rt|
 rt.eval('$v = strlen("PHP IS AWESOME");')
 puts rt['v'] # => 14
end
W
                   Ruby.PHP()                       U
                                                    P
                                                    S

Phuby::Runtime.php do |rt|
 rt.eval('$foo = array();')
 rt.eval('$foo["hello"] = "world";')

 foo = rt['foo'] # => #<Phuby::Array:0x101f8f848>
 p foo['hello'] # => ‘world’
end
W
            $PHP->Ruby();               U
                                        P
                                        S
class FUN
 def times
   puts "hello"
 end
end

Phuby::Runtime.php do |rt|
 rt['fun'] = FUN.new
 rt.eval('$fun->times();') # => hello
end
W
You got your PHP in my…   U
                          P
                          S
W
   Runtimes     U
                P
                S




Ruby      PHP
W
Embedded Runtimes   U
                    P
                    S
      Ruby

      PHP
W
Embedded Runtimes   U
                    P
                    S
      Ruby

      PHP
W
                        U
                        P
                        S

Circle of Terrible
     (In a fail bowl)
W
               U
               P
               S


Web Adapters
W
          U
          P
          S


WEBRick
W
             U
             P
             S


PHP Events
class Events < Phuby::Events      W
 def initialize req, res
   @req = req                     U
   @res = res
 end                              P
 def header value, op
                                  S
  k, v = *value.split(':', 2)
  if k.downcase == 'set-cookie'
    @res.cookies << v.strip
  else
    @res[k] = v.strip
  end
 end

 def write string
  @res.body ||= ''
  @res.body << string
 end

 def send_headers response_code
 end
end
W
          U
          P
          S


Adapter
module Phuby
 class PHPHandler < WEBrick::HTTPServlet::FileHandler
  def process verb, req, res
                                                                     W
    file = File.join(@root, req.path)

   Dir.chdir(File.dirname(file)) do
                                                                     U
    Phuby::Runtime.php do |rt|
      rt.eval("date_default_timezone_set('America/Los_Angeles');")   P
                                                                     S
      rt['logger'] = Logger.new($stdout)
      req.request_uri.query.split('&').each do |pair|
        k, v = pair.split '='
        rt["_GET"][k] = v
      end if req.request_uri.query

      req.query.each do |k,v|
       rt["_#{verb}"][k] = v
      end if :POST == verb

      # Set CGI server options
      req.meta_vars.each do |k,v|
        rt["_SERVER"][k] = v || ''
      end
      rt["_SERVER"]['REQUEST_URI'] = req.request_uri.path

      req.cookies.each do |cookie|
       rt["_COOKIE"][cookie.name] = CGI.unescape(cookie.value)
      end

      events = Events.new req, res

       rt.with_events(events) do
         File.open(file, 'rb') { |f| rt.eval f }
       end
     end
   end
   if res['Location']
     res['Location'] = CGI.unescape res['Location']
     res.status = 302
   end
  end
W
       U
       P
       S


Rack
W
                                     Rack is Hip           U
                                                           P
                                                           S
             Rack is totally
              sweet bro




http://www.flickr.com/photos/chromewavesdotorg/528814269/
W
            Phrack   U
                     P
                     S



• 50 Lines
• Totally Hip
class Rack::Phrack < Rack::File
 class Events < Struct.new(:code, :headers, :body)
   def write string; body << string; end
                                                                                   W
   def send_headers response_code; end

  def header value, op
                                                                                   U
   k, v = value.split(': ', 2)
   self.code = 302 if k == 'Location'
   headers[k] = [headers[k], Rack::Utils.unescape(v)].compact.join "n"
                                                                                   P
                                                                                   S
  end
 end

 def call env
  events = Events.new 200, {}, ''
  file = File.join @root, env['PATH_INFO']
  file = File.join file, "index.php" if File.directory?(file)

  return super unless file =~ /php$/

  Dir.chdir(File.dirname(file)) do
   Phuby::Runtime.php do |rt|
     rt.eval "date_default_timezone_set('America/Los_Angeles');" # *shrug*

     { Rack::Utils.parse_query(env['QUERY_STRING'])      => "_GET",
       Rack::Utils.parse_query(env['rack.input'].read) => "_POST",
       Rack::Utils.parse_query(env['HTTP_COOKIE'], ';') => "_COOKIE",
     }.each do |from, to|
       from.each { |k,v| rt[to][k] = v }
     end

     env.each { |k,v| rt['_SERVER'][k] = v || '' unless k =~ /^rack/ }
     rt["_SERVER"]['REQUEST_URI'] = env['PATH_INFO']

     rt.with_events(events) { open(file) { |f| rt.eval f } } # RUN!
    end
  end
  events.to_a
 end
end

Rack::Handler::WEBrick.run(Rack::Phrack.new(ARGV[0] || Dir.pwd), :Port => 10101)
W
               U
               P
               S


Phuby Blargh
W
                   U
                   P
                   S

DHH did it in 15
   minutes
W
                    U
                    P
                    S


We can do it in 2
Wordpress on Ruby Video


http://www.youtube.com/watch?v=MXERy8Y2eVo
Enterprise
Scalable software at its finest
Guiding Principles
Ruby does not scale
XML
      http://www.flickr.com/photos/drewm/3016905054/
scales
         http://www.flickr.com/photos/drewm/3016905054/
like
       http://www.flickr.com/photos/drewm/3016905054/
a
    http://www.flickr.com/photos/drewm/3016905054/
boss
       http://www.flickr.com/photos/drewm/3016905054/
<?XML?>




boss
       http://www.flickr.com/photos/drewm/3016905054/
W
        U
        P
        S



Trees
W
Ruby     U
         P
         S



2 + 10
W
    Ruby        U
                P
                S

     +


2          10
W
     Ruby Parser            U
                            P
                            S
                   +

2 + 10
             2         10
W
                   XML     U
                           P
                           S


<?xml version=”AWESOME”
   encoding=”’MERKIN” ?>
<root>
 <left />
 <right />
</root>
W
       XML            U
                      P
                      S

       root


left          right
W
              Nokogiri                     U
                                           P
                                           S

<root>
                            root
  <left />
  <right />
</root>
                     left          right
W
             ????                     U
                                      P
                                      S
    +                      root


2       10          left          right
W
        Enterprise                U
                                  P
                                  S
    +                  root


2       10      left          right
W
         U
         P
         S


“Uses”
W
                   U
                   P
                   S


Meta-programming
W
    Convert “foo” to “bar”                          U
                                                    P
                                                    S
sexml = Enterprise::SEXML DATA.read
sexml.xpath('//*[@value = "foo"]').each do |node|
 node['value'] = 'bar'
end

puts sexml.to_ruby

__END__
class Foo
end
foo = Foo.new
foo.hello
W
                U
                P
                S

class Foo
end
bar = Foo.new
bar.hello
W
                 U
                 P
                 S

Not Enterprise
   Enough
<?xml version="1.0" encoding="UTF-8"?>                                 W
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">                                                            U
 <xsl:template match="//*">
  <xsl:copy>                                                           P
   <xsl:if test="@type">
     <xsl:attribute name="type">                                       S
      <xsl:value-of select="@type" />
     </xsl:attribute>
   </xsl:if>
   <xsl:if test="@value">
     <xsl:attribute name="value">
      <xsl:choose>
        <xsl:when test="@value = 'foo'">bar</xsl:when>
        <xsl:otherwise>
         <xsl:value-of select="@value"/>
        </xsl:otherwise>
      </xsl:choose>
     </xsl:attribute>
   </xsl:if>
   <xsl:apply-templates />
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>                                 W
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">                                                            U
 <xsl:template match="//*">
  <xsl:copy>                                                           P
   <xsl:if test="@type">
     <xsl:attribute name="type">                                       S
      <xsl:value-of select="@type" />
     </xsl:attribute>
   </xsl:if>
   <xsl:if test="@value">
     <xsl:attribute name="value">
      <xsl:choose>
        <xsl:when test="@value = 'foo'">bar</xsl:when>
        <xsl:otherwise>
         <xsl:value-of select="@value"/>
        </xsl:otherwise>
      </xsl:choose>
     </xsl:attribute>
   </xsl:if>
   <xsl:apply-templates />
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>
W
                                            U
sexml = Enterprise::SEXML DATA.read         P
xslt = Nokogiri::XSLT(File.read(ARGV[0]))   S

doc = xslt.transform sexml
puts doc.to_ruby

__END__
class Foo
end
foo = Foo.new
foo.hello
http://www.flickr.com/photos/29364131@N07/3119439609/ http://www.flickr.com/photos/psd/2928326253/
<?XML?>
                                                                         <sucka />




http://www.flickr.com/photos/29364131@N07/3119439609/ http://www.flickr.com/photos/psd/2928326253/
W
         Poe's Law                 U
                                   P
                                   S


• Code as XML?
• The name “Enterprise”
• Everything about this project?
W
Spiral Downward   U
                  P
                  S
Enterprise Rails


• Rails isn't Enterprisey enough.
• We "fixed" that.
Enterprise Rails Video


http://www.youtube.com/watch?v=ar2eqEoMUTw
Actual Benefits!
• Several bugs in ruby2ruby and nokogiri
  were found while working on this.

• I could have fixed these bugs at any
  time, but I wasn't looking for them.

• Apparently a bad idea is a good reason
  to fix things.
Bringing it All
  Together
Phuby on Phails
Phuby on Phails Video


http://www.youtube.com/watch?v=lsWKjS6Vufw
Enterprise Phuby Rails


• We haven't written this yet…
 • It should only take about 30 min.
• How much should we charge for it?
Conclusion
It’s OK if your idea
       is bad
Just practice Good
   Engineering
     You know, for fun!
2009: Worst Year
 for Ruby Ever.
Together we can make
  2010 even worse
Thank You

Worst. Ideas. Ever.

  • 1.
    Worst. Ideas. Evar. TODO: Subtitle
  • 2.
    Scope • We’re nothere to trash on other ppl’s projects. • Not a worst practices show and tell. • Well engineered, but horrible ideas.
  • 3.
    Bios • We bothwork at AT&T Interactive. • We've done ruby for a long time. • Blah blah blah boring...
  • 4.
    Bios • We bothwork at AT&T Interactive. • We've done ruby for a long time. • Blah blah blah boring... NOTE: none of this presentation or software was supported, sanctioned, endorsed, or even tolerated by our employer.
  • 5.
  • 6.
    Aaron • Likes kittens,ponies, and vim. • Is totally in love with his mustache. • Prefers to write C code over ruby. Think about it: • nokogiri? C • johnson? C • never_say_die? C • psych? C • phuby? C • nfc? C • earworm? C • qrtools? C
  • 7.
    Ryan Davis • Likeskittens, ponies, and emacs. • Is totally in love with his ponytail. • Wishes Sting never left the Police. • Fears nothing except: • mushrooms • asparagus • Hates it when I sing. • Same colors, everyday. Redacted
  • 8.
    What is aBad Idea?
  • 9.
  • 10.
  • 11.
  • 12.
    Field Guide Spotting bad ideas in the wild • Well engineered & tested. • Useless-ish. • Poe’s Law. • Spiral nature.
  • 13.
    W Field Guide U Spotting bad ideas in the wild P S • Well engineered & tested. • Useless-ish. • Poe’s Law. • Spiral nature.
  • 14.
    W Well Engineered &Tested U P S • Bad Ideas != Bad Code. • Good Code + Tests > Horrible Idea. • Be wary of the well tested project!
  • 15.
    W Useless-ish U P S • They must be useless… ish. • They should do something. • Just not anything you need/want.
  • 16.
    W Poe’s Law U P "Without a winking smiley or other blatant display of S humour, it is impossible to create a parody of fundamentalism that someone won't mistake for the real thing," [1] "…it is hard to tell parodies of fundamentalism from the real thing, since they both seem equally insane. Conversely, real fundamentalism can easily be mistaken for a parody of fundamentalism." [2] [1] http://en.wikipedia.org/wiki/Poe's_law [2] http://rationalwiki.com/wiki/Poe's_Law [awesome] http://conservapedia.com/Poe's_law
  • 17.
    W Poe’s Law U P S • From high level, they can sound perfectly reasonable. • Solution looking for a problem. • They don't solve any immediate problems at hand. They generate them. • Everyone always ignores that guy in the corner asking “Really???”. I mean, c'mon… what does he know?
  • 18.
    W Spiral Nature U P S • The best part of Bad Ideas is that they build upon one another. • Hopefully with cyclic dependencies.
  • 19.
    Hypothetical Examples (Read: We haven't finished them… yet) • XML multi file format (a la java's jar format) • DRB over RFID • DRB over QR/Bar Code via webcams • Assembly optimized web pages • FFI
  • 20.
  • 21.
    Yoda • Bad ideascan be high level. • Test frameworks are the new IRC bot! • Yoda defines a spec language in the direction we think they should be.
  • 22.
    Bowling.yoda { "score0 for gutter game".it_will { bowling = Bowling.new 20.times { bowling.hit(0) } bowling.score 0.it_is? bowling.score 42.it_is_not! } }
  • 23.
    ./lib/yoda.rb:5:in `fail_me': Failme you did: 1 != 0 (Yoda::FailMe) from ./lib/yoda.rb:19:in `matches' from (eval):5:in `score' from example.rb:19 from ./lib/yoda.rb:45:in `it_will' from example.rb:15 from ./lib/yoda.rb:63:in `yoda' from example.rb:14
  • 24.
    W So Simple ItCan't Break U P S • 65 lines of Jedi Master Ruby. • 3 conditionals, 1 loop. • Flogs to 41.1, avg 4.1 / method. LOW! • How can you go wrong?
  • 25.
    W Useless, am I? U P S • Not exactly very expressive. • Then again, doesn't need to be.
  • 26.
    W Poe's got nothin'on Yoda U P S • Really? Another test framework? • Really?
  • 27.
    W The Force isEverywhere U P S • It is a test framework… • You can use it everywhere!
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
    When you canwrite in Assembly?
  • 33.
    Wilson • Bad ideas can be very low level. • Generates x86 machine code via a "natural" feeling ruby DSL. • Named after the very metal Wilson Bilkovich.
  • 34.
    Inline-C class Counter inlinedo |builder| builder.c " long cee(int n) { long i; for (i = 0;i<n+1;i++) {}; return i; }" end end
  • 35.
    Wilsasm class Counter defasm:asm2, :n do eax.xor eax edx.mov arg(0) from_ruby edx edx.inc count = self.label eax.inc eax.cmp edx jnz count to_ruby eax end end
  • 36.
    Wilsasm class Counter defasm:asm2, :n do eax.xor eax edx.mov arg(0) from_ruby edx edx.inc count = self.label eax.inc eax.cmp edx jnz count to_ruby eax end end
  • 37.
    Benchmarks! % rm -r~/.ruby_inline; ./bench.rb 1_000_000 1_000 # of iterations = 1000000 $n = 1000 user system total real null_time 0.120000 0.000000 0.120000 ( 0.122507) cee_nil 0.280000 0.000000 0.280000 ( 0.279552) asm_nil 0.280000 0.000000 0.280000 ( 0.275498) ruby_nil 0.370000 0.000000 0.370000 ( 0.372142) cee 0.830000 0.010000 0.840000 ( 0.837607) asm2 0.830000 0.000000 0.830000 ( 0.839430) asm 3.520000 0.000000 3.520000 ( 3.542521) ruby 98.970000 0.430000 99.400000 (101.903256)
  • 38.
    W Whip-Smart U P S • Generates machine code directly: • No dependencies. • No external resources. • Parses the 60 page x86 spec into instructions and their opcodes.
  • 39.
    W "Uses" U P S • Good at writing really fast code. • And crashing. Fast. • I don't think anyone uses this. • (I hope not)
  • 40.
    W Poe Man's Dispatch U P S • The original intent was to write a pure ruby method dispatch function. • But that is hard. • And we got laid off of Rubinius.
  • 41.
    W Spiral? U P S • It was intended to be the core of a new ruby implementation. • How much more spiral do you want?
  • 42.
  • 43.
  • 44.
  • 45.
    Marshal data istoo hard to read Marshal.dump nil # => "004b0" Unreadable, therefore useless
  • 46.
    YAML is toohard to read YAML.dump nil # => "--- n" Unreadable, therefore useless
  • 47.
  • 48.
  • 49.
    W U P S The Guts
  • 50.
    W Language U P Dependencies S • Ruby (of course) • YAML (psych) • XML / HTML (nokogiri)
  • 51.
    W Data is a Tree U P S o={ :foo => [1,2,3,4], 'mom' => Struct.new(:data).new('bar') }
  • 52.
    W Ruby Data Graph U P o S :foo mom 1 2 3 4 :data bar
  • 53.
    W HTML data graph U P html S body table tr td td td
  • 54.
    W U P S Translation
  • 55.
    W U P S HTML data is a subset of Ruby
  • 56.
    W U P S YAML to the rescue
  • 57.
    W YAML Representation U P S --- :foo: -1 -2 -3 -4 mom: !ruby/struct :data: bar
  • 58.
    W Ruby => YAML AST U P S Stream Document Mapping Scalar :foo Sequence Scalar mom Mapping Scalar 1 Scalar 2 Scalar 3 Scalar 4 Scalar :data Scalar bar
  • 59.
    W YAML AST => HTML U P S HTML BODY DL DT :foo DD / OL DT mom DD / DL LI 1 LI 2 LI 3 LI 4 DT :data DD bar
  • 60.
    W Sample Use U P S o={ :foo => [1,2,3,4], 'bar' => Struct.new(:foo).new('bar') } Wank::HTML::Marshal.dump(o)
  • 61.
    <html xmlns="http://www.w3.org/1999/xhtml"> <head> W <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> U <body> <dl> P <dt>bar</dt> <dd> S <dl class="!ruby/struct "> <dt>foo</dt> <dd>bar</dd> </dl> </dd> <dt>:foo</dt> <dd> <ol> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ol> </dd> </dl> </body> </html>
  • 62.
  • 63.
    W Wank in Style! U P S dl { border: solid green; } dt:after { content: " => "; } ol { border: solid blue; }
  • 64.
  • 65.
    W The Circleof U P Terrible S Ruby YAML YAML HTML
  • 66.
    W Wank over DRb U P S HTML!
  • 67.
    W Wank over DRb U P S DRb::Marshal = Wank::HTML::Marshal
  • 68.
    W Wank on Rack U P S module Rack class Wank include Wank::HTML def call env [ 200, {}, Marshal.dump("hello") ] end end end
  • 69.
    W Wank on Rails U P S class WankController def show @wanker = Wanker.find(params[:id]) render :text => Wank::HTML::Marshal.dump(@wanker) end end
  • 70.
    W U P S You can Wank Anywhere!
  • 71.
  • 72.
    Never Say Die •Rescue from segfaults • Create segfaults
  • 73.
    libsigsegv • pageable virtualmemory • memory mapped access to databases • generational garbage collectors • stack overflow handlers • distributed shared memory
  • 74.
    libsigsegv • pageable virtualmemory HUH? • memory mapped access to databases • generational garbage collectors • stack overflow handlers • distributed shared memory
  • 75.
    Trap INT trap(“INT”) do puts "haha! no!" end
  • 76.
    Trap SEGV begin ...# something dangerous rescue NeverSayDie ... # Fix your memory! end
  • 77.
    W U P S Fully Tested
  • 78.
    W U P S NeverSayDie::segv
  • 79.
    W U P begin S NeverSayDie.segv rescue NeverSayDie => maverick return maverick # => end
  • 80.
    W U P begin S NeverSayDie.segv rescue NeverSayDie => maverick return maverick # => end
  • 81.
  • 82.
    W Uselessish U P S • If you think you need this…
  • 83.
    W Uselessish U P S • If you think you need this… • well, you probably do.
  • 84.
    W Poe's Law U P S begin asm :thuper_optimized do eax.mov 0 ecx.mov 10 count = self.label eax.add 1 count.loop to_ruby eax end rescue NeverSayDie # run the slow one :( 1.upto(10) do; end end # really??
  • 85.
    W Never Say Die, on Rails U P S class SegvController < ... def index ... rescue NeverSayDie ... # Yay! More uptime! end end
  • 86.
  • 87.
    Because Rails programmers are secretly PHP programmers
  • 88.
  • 89.
  • 90.
  • 91.
    Source of BadIdeas • Ryan came up with the idea of Phuby. • Aaron implemented phuby. • Ryan is counting this as a win x 2.
  • 92.
    W U P S Well Engineered
  • 93.
    Ruby var =>PHP Ruby C PHP Proxy Weak Ref Table PHP (runtime) Ruby
  • 94.
    Ruby var =>PHP Ruby C PHP Proxy Weak Ref Table PHP (runtime) Ruby
  • 95.
    Weak Ref Table •PHP object memory location (INT) • VALUE
  • 96.
    PHP calling Ruby Ruby C PHP Proxy Weak Ref Table PHP (runtime) Ruby
  • 97.
    PHP calling Ruby Ruby C PHP Proxy Weak Ref Table PHP (runtime) Ruby
  • 98.
    Ruby calling PHP Ruby C PHP Proxy Ruby PHP (runtime)
  • 99.
    Ruby calling PHP Ruby C PHP Proxy Ruby PHP (runtime) Proxy (object)
  • 100.
    W Ruby.PHP() U P S Phuby::Runtime.php do |rt| rt.eval('$v = strlen("PHP IS AWESOME");') puts rt['v'] # => 14 end
  • 101.
    W Ruby.PHP() U P S Phuby::Runtime.php do |rt| rt.eval('$foo = array();') rt.eval('$foo["hello"] = "world";') foo = rt['foo'] # => #<Phuby::Array:0x101f8f848> p foo['hello'] # => ‘world’ end
  • 102.
    W $PHP->Ruby(); U P S class FUN def times puts "hello" end end Phuby::Runtime.php do |rt| rt['fun'] = FUN.new rt.eval('$fun->times();') # => hello end
  • 103.
    W You got yourPHP in my… U P S
  • 104.
    W Runtimes U P S Ruby PHP
  • 105.
    W Embedded Runtimes U P S Ruby PHP
  • 106.
    W Embedded Runtimes U P S Ruby PHP
  • 107.
    W U P S Circle of Terrible (In a fail bowl)
  • 108.
    W U P S Web Adapters
  • 109.
    W U P S WEBRick
  • 110.
    W U P S PHP Events
  • 111.
    class Events <Phuby::Events W def initialize req, res @req = req U @res = res end P def header value, op S k, v = *value.split(':', 2) if k.downcase == 'set-cookie' @res.cookies << v.strip else @res[k] = v.strip end end def write string @res.body ||= '' @res.body << string end def send_headers response_code end end
  • 112.
    W U P S Adapter
  • 113.
    module Phuby classPHPHandler < WEBrick::HTTPServlet::FileHandler def process verb, req, res W file = File.join(@root, req.path) Dir.chdir(File.dirname(file)) do U Phuby::Runtime.php do |rt| rt.eval("date_default_timezone_set('America/Los_Angeles');") P S rt['logger'] = Logger.new($stdout) req.request_uri.query.split('&').each do |pair| k, v = pair.split '=' rt["_GET"][k] = v end if req.request_uri.query req.query.each do |k,v| rt["_#{verb}"][k] = v end if :POST == verb # Set CGI server options req.meta_vars.each do |k,v| rt["_SERVER"][k] = v || '' end rt["_SERVER"]['REQUEST_URI'] = req.request_uri.path req.cookies.each do |cookie| rt["_COOKIE"][cookie.name] = CGI.unescape(cookie.value) end events = Events.new req, res rt.with_events(events) do File.open(file, 'rb') { |f| rt.eval f } end end end if res['Location'] res['Location'] = CGI.unescape res['Location'] res.status = 302 end end
  • 114.
    W U P S Rack
  • 115.
    W Rack is Hip U P S Rack is totally sweet bro http://www.flickr.com/photos/chromewavesdotorg/528814269/
  • 116.
    W Phrack U P S • 50 Lines • Totally Hip
  • 117.
    class Rack::Phrack <Rack::File class Events < Struct.new(:code, :headers, :body) def write string; body << string; end W def send_headers response_code; end def header value, op U k, v = value.split(': ', 2) self.code = 302 if k == 'Location' headers[k] = [headers[k], Rack::Utils.unescape(v)].compact.join "n" P S end end def call env events = Events.new 200, {}, '' file = File.join @root, env['PATH_INFO'] file = File.join file, "index.php" if File.directory?(file) return super unless file =~ /php$/ Dir.chdir(File.dirname(file)) do Phuby::Runtime.php do |rt| rt.eval "date_default_timezone_set('America/Los_Angeles');" # *shrug* { Rack::Utils.parse_query(env['QUERY_STRING']) => "_GET", Rack::Utils.parse_query(env['rack.input'].read) => "_POST", Rack::Utils.parse_query(env['HTTP_COOKIE'], ';') => "_COOKIE", }.each do |from, to| from.each { |k,v| rt[to][k] = v } end env.each { |k,v| rt['_SERVER'][k] = v || '' unless k =~ /^rack/ } rt["_SERVER"]['REQUEST_URI'] = env['PATH_INFO'] rt.with_events(events) { open(file) { |f| rt.eval f } } # RUN! end end events.to_a end end Rack::Handler::WEBrick.run(Rack::Phrack.new(ARGV[0] || Dir.pwd), :Port => 10101)
  • 118.
    W U P S Phuby Blargh
  • 119.
    W U P S DHH did it in 15 minutes
  • 120.
    W U P S We can do it in 2
  • 121.
    Wordpress on RubyVideo http://www.youtube.com/watch?v=MXERy8Y2eVo
  • 122.
  • 123.
  • 124.
  • 125.
    XML http://www.flickr.com/photos/drewm/3016905054/
  • 126.
    scales http://www.flickr.com/photos/drewm/3016905054/
  • 127.
    like http://www.flickr.com/photos/drewm/3016905054/
  • 128.
    a http://www.flickr.com/photos/drewm/3016905054/
  • 129.
    boss http://www.flickr.com/photos/drewm/3016905054/
  • 130.
    <?XML?> boss http://www.flickr.com/photos/drewm/3016905054/
  • 132.
    W U P S Trees
  • 133.
    W Ruby U P S 2 + 10
  • 134.
    W Ruby U P S + 2 10
  • 135.
    W Ruby Parser U P S + 2 + 10 2 10
  • 136.
    W XML U P S <?xml version=”AWESOME” encoding=”’MERKIN” ?> <root> <left /> <right /> </root>
  • 137.
    W XML U P S root left right
  • 138.
    W Nokogiri U P S <root> root <left /> <right /> </root> left right
  • 139.
    W ???? U P S + root 2 10 left right
  • 140.
    W Enterprise U P S + root 2 10 left right
  • 141.
    W U P S “Uses”
  • 142.
    W U P S Meta-programming
  • 143.
    W Convert “foo” to “bar” U P S sexml = Enterprise::SEXML DATA.read sexml.xpath('//*[@value = "foo"]').each do |node| node['value'] = 'bar' end puts sexml.to_ruby __END__ class Foo end foo = Foo.new foo.hello
  • 144.
    W U P S class Foo end bar = Foo.new bar.hello
  • 145.
    W U P S Not Enterprise Enough
  • 146.
    <?xml version="1.0" encoding="UTF-8"?> W <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/ Transform"> U <xsl:template match="//*"> <xsl:copy> P <xsl:if test="@type"> <xsl:attribute name="type"> S <xsl:value-of select="@type" /> </xsl:attribute> </xsl:if> <xsl:if test="@value"> <xsl:attribute name="value"> <xsl:choose> <xsl:when test="@value = 'foo'">bar</xsl:when> <xsl:otherwise> <xsl:value-of select="@value"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:apply-templates /> </xsl:copy> </xsl:template> </xsl:stylesheet>
  • 147.
    <?xml version="1.0" encoding="UTF-8"?> W <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/ Transform"> U <xsl:template match="//*"> <xsl:copy> P <xsl:if test="@type"> <xsl:attribute name="type"> S <xsl:value-of select="@type" /> </xsl:attribute> </xsl:if> <xsl:if test="@value"> <xsl:attribute name="value"> <xsl:choose> <xsl:when test="@value = 'foo'">bar</xsl:when> <xsl:otherwise> <xsl:value-of select="@value"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:apply-templates /> </xsl:copy> </xsl:template> </xsl:stylesheet>
  • 148.
    W U sexml = Enterprise::SEXML DATA.read P xslt = Nokogiri::XSLT(File.read(ARGV[0])) S doc = xslt.transform sexml puts doc.to_ruby __END__ class Foo end foo = Foo.new foo.hello
  • 149.
  • 150.
    <?XML?> <sucka /> http://www.flickr.com/photos/29364131@N07/3119439609/ http://www.flickr.com/photos/psd/2928326253/
  • 151.
    W Poe's Law U P S • Code as XML? • The name “Enterprise” • Everything about this project?
  • 152.
  • 153.
    Enterprise Rails • Railsisn't Enterprisey enough. • We "fixed" that.
  • 154.
  • 155.
    Actual Benefits! • Severalbugs in ruby2ruby and nokogiri were found while working on this. • I could have fixed these bugs at any time, but I wasn't looking for them. • Apparently a bad idea is a good reason to fix things.
  • 156.
  • 157.
  • 158.
    Phuby on PhailsVideo http://www.youtube.com/watch?v=lsWKjS6Vufw
  • 159.
    Enterprise Phuby Rails •We haven't written this yet… • It should only take about 30 min. • How much should we charge for it?
  • 160.
  • 161.
    It’s OK ifyour idea is bad
  • 162.
    Just practice Good Engineering You know, for fun!
  • 163.
    2009: Worst Year for Ruby Ever.
  • 164.
    Together we canmake 2010 even worse
  • 165.

Editor's Notes

  • #13 They must be really well written to overcome the fact that they&apos;re horrible.
  • #29 Only 2 assertions (it_is?, it_is_not?), but really a test framework only needs 1, so that is 2x!
  • #58 HTML contains Strings, Maps, Lists. How do we translate to Ruby?
  • #112 We have two runtimes
  • #113 Let the ruby runtime call in to PHP, and the PHP runtime call in to ruby
  • #114 Let the ruby runtime call in to PHP, and the PHP runtime call in to ruby
  • #121 this code is small so that you will not read it.
  • #125 This is small so that you *don&amp;#x2019;t* read it