SlideShare a Scribd company logo
Having Fun Programming!
Have Fun
Programming
Programming for
      Fun!
@tenderlove
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
...
Aaron Patterson
AT&T, AT&T logo and all AT&T related marks are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies.
First
Having Fun Programming!
Ujihisa!
Q: How can I
                                                             enjoy
                                                        programming?




http://www.flickr.com/photos/recompile_net/3733132232/
A: Use Vim!




http://www.flickr.com/photos/recompile_net/3732334373/
•
•
•
•
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Ruby
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
class
end
6.times {
            .new
}
Having Fun Programming!
Thread.new do
        .    ()
end
Thread.new do
      .    ()
end
(Thread.list -[Thread.main]).each
{ |x|
  x.join
}
Having Fun Programming!
• Ruby
•C
• Java
• Lisp
• PHP?
Having Fun Programming!
Having Fun Programming!
We Speak

•
•
•
•
.count


.count
;_;
";_;".encode(   ) # => ":'("
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
/
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Ruby Brigades
Seattle.rb
Hack Night
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
!!!!
!
!
Having Fun Programming!
Hallway Track
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
•
•
•
•
•
• Rails 3
•
• XML
• YAML
0 bugs in Ruby 1.9
50% used Ruby 1.9
Having Fun Programming!
Having Fun Programming!
YAML
Psych   Syck
Syck

• Ruby 1.8     1.9

• YAML 1.0 (         ) parser   emitter

•
Psych

• Ruby >= 1.9.2
• libyaml
• YAML 1.1 parser   emitter

•
YAML
Ruby 1.8 / 1.9


require 'yaml'

YAML.load_file('some_file.yml')
YAML.load('--- hello world!')
Ruby 1.9.2 / Psych


require 'psych'

Psych.load_file('some_file.yml')
Psych.load('--- hello world!')
1.9.2 Opt-in


require 'yaml'

YAML::ENGINE.yamler = 'psych'

YAML.load('--- this is psych')
YAML
require 'psych'

Psych.dump { :foo => 'bar' }
{ :hello => 'world' }.to_yaml
JSON
YAML Map


---
foo: bar
YAML Map


---
'foo': 'bar'
YAML Map


---
{ 'foo': 'bar' }
require 'psych'

Psych.to_json { :foo => 'bar' }
Psych
Emitter
class Foo
  def initialize
    @greeting = 'world'
  end

 def encode_with(coder)
   coder['hello'] = @greeting
 end

  def init_with(coder)
    @greeting = coder['hello']
  end
end
Psych.dump


--- !ruby/object:Foo
hello: world
Psych.load



#<Foo:0x000001009f6770 @greeting="world">
Independent
class Foo
  def initialize
    @greeting = 'world'
  end

  def encode_with(coder)
    coder['hello'] = @greeting
  end

  def init_with(coder)
    @greeting = coder['hello']
  end
end
YAML            JSON


Psych.dump    Foo.new
Psych.to_json Foo.new
class XMLDumper < Psych::Handler
  def self.dump(object)
    dumper = new
    viz = Psych::Visitors::YAMLTree.new({}, dumper)
    viz << object
    dumper.doc.to_xml
  end

 attr_reader :doc

 def initialize
   @doc      = Nokogiri::XML::Document.new
   @doc.root = @doc.create_element 'root'
   @tags     = []
   @stack    = [@doc.root]
 end

 def start_mapping(anchor, tag, implicit, style)
   tag = @doc.create_element('table')
   @stack.last << tag
   @stack      << tag
 end

 def end_mapping
   @stack.pop
 end

  def scalar(value, anchor, tag, *args)
    @stack.last << @doc.create_element('tr').tap do |tag|
      tag << @doc.create_element('td', value)
    end
  end
end
YAML, JSON
                  XML

Psych.dump     Foo.new
Psych.to_json Foo.new
XMLDumper.dump Foo.new
class HTMLDumper < XMLDumper
  def initialize
    @doc      = Nokogiri::HTML::Document.new
    @doc.root = @doc.create_element('html')
    @doc.root << @doc.create_element('body')
    @tags     = []
    @stack    = [@doc.root.children.first]
  end
end
YAML, JSON, XML
           HTML

Psych.dump        Foo.new
Psych.to_json     Foo.new
XMLDumper.dump    Foo.new
HTMLDumper.dump   Foo.new
module Marshalable
  module ClassMethods
    def _load data
      x = allocate
      x.init_with Marshal.load data
      x
    end
  end

 def self.included klass
   klass.extend ClassMethods
 end

  def _dump o
    coder = {}
    encode_with coder
    Marshal.dump coder
  end
end

class Foo; include Marshalable; end
YAML, JSON, XML,
     HTML   Marshal
Psych.dump        Foo.new
Psych.to_json     Foo.new
XMLDumper.dump    Foo.new
HTMLDumper.dump   Foo.new
Marshal.dump      Foo.new
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
SQLite3-Ruby
SQLite3-Ruby

• SQLite3
• Jamis Buck
• SWIG
Having Fun Programming!
require 'sqlite3'

connection =
  SQLite3::Database.new('file.sqlite3')
Pro Tip


require 'sqlite3'

connection =
  SQLite3::Database.new(':memory:')
Pro Tip


require 'sqlite3'

connection =
  SQLite3::Database.new(':memory:')
connection.execute('CREATE TABLE foo(id INTEGER)')


connection.execute('INSERT INTO foo (id) VALUES (?)', [10])
stmt = connection.prepare('SELECT * FROM foo WHERE id = ?')

stmt.bind_param(1, 10)

stmt.each do |row|
  p row
end
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
SQLite3
•   1: API


•   2:


•   3:
: API
struct sqlite3_vfs {
   int iVersion;             /* Structure version number */
   int szOsFile;             /* Size of subclassed sqlite3_file */
   int mxPathname;           /* Maximum file pathname length */
   sqlite3_vfs *pNext;       /* Next registered VFS */
   const char *zName;        /* Name of this virtual file system */
   void *pAppData;           /* Pointer to application-specific data */
   int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
                 int flags, int *pOutFlags);
   int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
   int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
   int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
   void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
   void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
   void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
   void (*xDlClose)(sqlite3_vfs*, void*);
   int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
   int (*xSleep)(sqlite3_vfs*, int microseconds);
   int (*xCurrentTime)(sqlite3_vfs*, double*);
   int (*xGetLastError)(sqlite3_vfs*, int, char *);
   /* New fields may be appended in figure versions. The iVersion
   ** value will increment whenever this happens. */
};
IO Hooks
2:
static int rbFile_close(sqlite3_file * ctx)
{
  rubyFilePtr rfile = (rubyFilePtr)ctx;
  VALUE file = rfile->file;
  rb_funcall(file, rb_intern("close"), 0);
  return SQLITE_OK;
}
class VFS < SQLite3::VFS
  def open(name, flags)
    OurFile.new(name, flags)
  end
end

class OurFile
  def read(...); ... end
  def write(...); ... end
end
SQLite Database
__END__ + DATA
class EvilVFS < SQLite3::VFS
  def open name, flags
    DATABase.new name, flags
  end
end

class DATABase < SQLite3::VFS::File
  def initialize name, flags
    super
    @store = File.open(name, File::RDWR | File::CREAT)
    @offset = 0

   if File.expand_path(__FILE__) == name
     @store.seek DATA.pos
     @offset = DATA.pos
   end
 end

 def close
   @store.close
 end

 def read amt, offset
   @store.seek(offset + @offset)
   @store.read amt
 end

 def write data, offset
   @store.seek(offset + @offset)
   @store.write data
 end

 def sync opts
   @store.fsync
 end

  def file_size
    File.size(@store.path) - @offset
  end
end
SQLite3.vfs_register(EvilVFS.new)
db = SQLite3::Database.new(__FILE__, nil, 'EvilVFS')

db.execute(<<-eosql)
  create table if not exists
  users(id integer primary key, name string)
eosql

100.times {
  db.execute(<<-eosql, 'tenderlove')
    insert into users(name) values (?)
  eosql
}

p db.execute('select count(*) from users')

__END__
3:
Having Fun Programming!
http://gist.github.com/319224/
SQLite3-Ruby
• Ruby 1.9
• 1000       (   )
require 'sqlite3'

db = SQLite3::Database.new(':memory:')

db.execute('CREATE TABLE foo(id INTEGER, name VARCHAR)')
db.execute('INSERT INTO foo (id, name) VALUES (?,?)',
[10,'hello world'])

rows = db.execute('SELECT name FROM foo')
p rows.first.first.encoding # => #<Encoding:UTF-8>

Encoding.default_internal = 'EUC-JP'

rows = db.execute('SELECT name FROM foo')
p rows.first.first.encoding # => #<Encoding:EUC-JP>
require 'sqlite3'

db = SQLite3::Database.new(':memory:')

db.execute('CREATE TABLE foo(id INTEGER, name VARCHAR)')
db.execute('INSERT INTO foo (id, name) VALUES (?,?)',
[10,'hello world'])

rows = db.execute('SELECT name FROM foo')
p rows.first.first.encoding # => #<Encoding:UTF-8>

Encoding.default_internal = 'EUC-JP'

rows = db.execute('SELECT name FROM foo')
p rows.first.first.encoding # => #<Encoding:EUC-JP>
require 'sqlite3'

db = SQLite3::Database.new(':memory:')

db.execute('CREATE TABLE foo(id INTEGER, name VARCHAR)')
db.execute('INSERT INTO foo (id, name) VALUES (?,?)',
[10,'hello world'])

rows = db.execute('SELECT name FROM foo')
p rows.first.first.encoding # => #<Encoding:UTF-8>

Encoding.default_internal = 'EUC-JP'

rows = db.execute('SELECT name FROM foo')
p rows.first.first.encoding # => #<Encoding:EUC-JP>
(SELECT                         )
                    1.2.5             1.3.0

1000

 100

  10

   1

 0.1

0.01
       500   1000     1500   2000   2500      3000   3500
PHP + Ruby
Phuby!
Ruby.PHP()


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

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
$PHP->Ruby();
class FUN
  def times
    puts "hello"
  end
end

Phuby::Runtime.php do |rt|
  rt['fun'] = FUN.new
  rt.eval('$fun->times();') # => hello
end
PHP
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Variable
 Ruby
PHP
rt['foo'] = Foo.new
Ruby          C        PHP

  Weak
              Proxy
Reference               PHP
            (runtime)
  Table




  Ruby
Ruby          C        PHP

  Weak
              Proxy
Reference               PHP
            (runtime)
  Table




  Ruby
PHP   Ruby
$foo->bar();
Ruby          C        PHP

  Weak
              Proxy
Reference               PHP
            (runtime)
  Table




  Ruby
Ruby          C        PHP

  Weak
              Proxy
Reference               PHP
            (runtime)
  Table




  Ruby
Ruby   PHP
rt['foo'].bar()
Ruby      C        PHP


         Proxy
Ruby               PHP
       (runtime)
Ruby      C        PHP


         Proxy
Ruby               PHP
       (runtime)




        Proxy
       (object)
Phuby
PHP + WEBrick
      =
    Blog
Having Fun Programming!
#!/usr/bin/env ruby

require 'rubygems'
require 'phuby'
require 'rack'

##
# Rack::Phrack is a Rack handler that will evaulate and serve PHP files.

class Rack::Phrack < Rack::File
  class Events < Struct.new(:code, :headers, :body)
    def write string; body << string; end
    def send_headers response_code;   end

    def header value, op
      k, v = value.split(': ', 2)
      self.code = 302 if k == 'Location'
      headers[k] = [headers[k], Rack::Utils.unescape(v)].compact.join "n"
    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)
Client



  Phrack



PHPRuntime
Client



  Phrack



PHPRuntime
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Having Fun Programming!
Special Thanks!
aka @masuidrive
zenspider
Special Request
One Click Installer




    Luis Lavena
Having Fun Programming!
Having Fun Programming!
Ad

More Related Content

What's hot (17)

Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
Lin Yo-An
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionFunctional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures edition
osfameron
 
extending-php
extending-phpextending-php
extending-php
tutorialsruby
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
Nikita Popov
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
Nikita Popov
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
garux
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
Tom Crinson
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
julien pauli
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipper
osfameron
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
Wes Oldenbeuving
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In Python
Marwan Osman
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
Andrew Shitov
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
osfameron
 
An (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonAn (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to Python
Nicholas Tollervey
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
osfameron
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
Lin Yo-An
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionFunctional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures edition
osfameron
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
Nikita Popov
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
Nikita Popov
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
garux
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
Tom Crinson
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipper
osfameron
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In Python
Marwan Osman
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
osfameron
 
An (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonAn (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to Python
Nicholas Tollervey
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
osfameron
 

Similar to Having Fun Programming! (20)

Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
.toster
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
✅ William Pinaud
 
Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9
Aaron Patterson
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
Ben Scofield
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
PHP Workshop Notes
PHP Workshop NotesPHP Workshop Notes
PHP Workshop Notes
Pamela Fox
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
Ígor Bonadio
 
DataMapper
DataMapperDataMapper
DataMapper
Yehuda Katz
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
Masahiro Nagano
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
Maarten Balliauw
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
Younggun Kim
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
Ian Barber
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
Troy Miles
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
Iftekhar Eather
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
kaushik_sathupadi
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
Muthu Vinayagam
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
Christian Trabold
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
.toster
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
✅ William Pinaud
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
Ben Scofield
 
PHP Workshop Notes
PHP Workshop NotesPHP Workshop Notes
PHP Workshop Notes
Pamela Fox
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
Ígor Bonadio
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
Masahiro Nagano
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
Maarten Balliauw
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
Younggun Kim
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
Ian Barber
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
Troy Miles
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
Iftekhar Eather
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
Muthu Vinayagam
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
Christian Trabold
 
Ad

More from Aaron Patterson (7)

RubyConf Argentina 2011
RubyConf Argentina 2011RubyConf Argentina 2011
RubyConf Argentina 2011
Aaron Patterson
 
Nordic Ruby 2011
Nordic Ruby 2011Nordic Ruby 2011
Nordic Ruby 2011
Aaron Patterson
 
RailsConf 2011 Keynote
RailsConf 2011 KeynoteRailsConf 2011 Keynote
RailsConf 2011 Keynote
Aaron Patterson
 
Behind the Curtain
Behind the CurtainBehind the Curtain
Behind the Curtain
Aaron Patterson
 
ZOMG WHY IS THIS CODE SO SLOW
ZOMG WHY IS THIS CODE SO SLOWZOMG WHY IS THIS CODE SO SLOW
ZOMG WHY IS THIS CODE SO SLOW
Aaron Patterson
 
RubyConf Brazil 2010
RubyConf Brazil 2010RubyConf Brazil 2010
RubyConf Brazil 2010
Aaron Patterson
 
Worst. Ideas. Ever.
Worst. Ideas. Ever.Worst. Ideas. Ever.
Worst. Ideas. Ever.
Aaron Patterson
 
Ad

Recently uploaded (20)

Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 

Having Fun Programming!

  • 8. ...
  • 10. AT&T, AT&T logo and all AT&T related marks are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies.
  • 11. First
  • 14. Q: How can I enjoy programming? http://www.flickr.com/photos/recompile_net/3733132232/
  • 22. Ruby
  • 29. Thread.new do . () end Thread.new do . () end (Thread.list -[Thread.main]).each { |x| x.join }
  • 31. • Ruby •C • Java • Lisp • PHP?
  • 36. ;_; ";_;".encode( ) # => ":'("
  • 42. !
  • 49. /
  • 61. !!!!
  • 62. !
  • 63. !
  • 70. • Rails 3 • • XML • YAML
  • 71. 0 bugs in Ruby 1.9
  • 75. YAML Psych Syck
  • 76. Syck • Ruby 1.8 1.9 • YAML 1.0 ( ) parser emitter •
  • 77. Psych • Ruby >= 1.9.2 • libyaml • YAML 1.1 parser emitter •
  • 78. YAML
  • 79. Ruby 1.8 / 1.9 require 'yaml' YAML.load_file('some_file.yml') YAML.load('--- hello world!')
  • 80. Ruby 1.9.2 / Psych require 'psych' Psych.load_file('some_file.yml') Psych.load('--- hello world!')
  • 81. 1.9.2 Opt-in require 'yaml' YAML::ENGINE.yamler = 'psych' YAML.load('--- this is psych')
  • 82. YAML
  • 83. require 'psych' Psych.dump { :foo => 'bar' } { :hello => 'world' }.to_yaml
  • 84. JSON
  • 89. Psych
  • 91. class Foo def initialize @greeting = 'world' end def encode_with(coder) coder['hello'] = @greeting end def init_with(coder) @greeting = coder['hello'] end end
  • 94. Independent class Foo def initialize @greeting = 'world' end def encode_with(coder) coder['hello'] = @greeting end def init_with(coder) @greeting = coder['hello'] end end
  • 95. YAML JSON Psych.dump Foo.new Psych.to_json Foo.new
  • 96. class XMLDumper < Psych::Handler def self.dump(object) dumper = new viz = Psych::Visitors::YAMLTree.new({}, dumper) viz << object dumper.doc.to_xml end attr_reader :doc def initialize @doc = Nokogiri::XML::Document.new @doc.root = @doc.create_element 'root' @tags = [] @stack = [@doc.root] end def start_mapping(anchor, tag, implicit, style) tag = @doc.create_element('table') @stack.last << tag @stack << tag end def end_mapping @stack.pop end def scalar(value, anchor, tag, *args) @stack.last << @doc.create_element('tr').tap do |tag| tag << @doc.create_element('td', value) end end end
  • 97. YAML, JSON XML Psych.dump Foo.new Psych.to_json Foo.new XMLDumper.dump Foo.new
  • 98. class HTMLDumper < XMLDumper def initialize @doc = Nokogiri::HTML::Document.new @doc.root = @doc.create_element('html') @doc.root << @doc.create_element('body') @tags = [] @stack = [@doc.root.children.first] end end
  • 99. YAML, JSON, XML HTML Psych.dump Foo.new Psych.to_json Foo.new XMLDumper.dump Foo.new HTMLDumper.dump Foo.new
  • 100. module Marshalable module ClassMethods def _load data x = allocate x.init_with Marshal.load data x end end def self.included klass klass.extend ClassMethods end def _dump o coder = {} encode_with coder Marshal.dump coder end end class Foo; include Marshalable; end
  • 101. YAML, JSON, XML, HTML Marshal Psych.dump Foo.new Psych.to_json Foo.new XMLDumper.dump Foo.new HTMLDumper.dump Foo.new Marshal.dump Foo.new
  • 108. require 'sqlite3' connection = SQLite3::Database.new('file.sqlite3')
  • 109. Pro Tip require 'sqlite3' connection = SQLite3::Database.new(':memory:')
  • 110. Pro Tip require 'sqlite3' connection = SQLite3::Database.new(':memory:')
  • 111. connection.execute('CREATE TABLE foo(id INTEGER)') connection.execute('INSERT INTO foo (id) VALUES (?)', [10])
  • 112. stmt = connection.prepare('SELECT * FROM foo WHERE id = ?') stmt.bind_param(1, 10) stmt.each do |row| p row end
  • 117. 1: API • 2: • 3:
  • 118. : API struct sqlite3_vfs { int iVersion; /* Structure version number */ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); void (*xDlClose)(sqlite3_vfs*, void*); int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); int (*xGetLastError)(sqlite3_vfs*, int, char *); /* New fields may be appended in figure versions. The iVersion ** value will increment whenever this happens. */ };
  • 120. 2:
  • 121. static int rbFile_close(sqlite3_file * ctx) { rubyFilePtr rfile = (rubyFilePtr)ctx; VALUE file = rfile->file; rb_funcall(file, rb_intern("close"), 0); return SQLITE_OK; }
  • 122. class VFS < SQLite3::VFS def open(name, flags) OurFile.new(name, flags) end end class OurFile def read(...); ... end def write(...); ... end end
  • 125. class EvilVFS < SQLite3::VFS def open name, flags DATABase.new name, flags end end class DATABase < SQLite3::VFS::File def initialize name, flags super @store = File.open(name, File::RDWR | File::CREAT) @offset = 0 if File.expand_path(__FILE__) == name @store.seek DATA.pos @offset = DATA.pos end end def close @store.close end def read amt, offset @store.seek(offset + @offset) @store.read amt end def write data, offset @store.seek(offset + @offset) @store.write data end def sync opts @store.fsync end def file_size File.size(@store.path) - @offset end end
  • 126. SQLite3.vfs_register(EvilVFS.new) db = SQLite3::Database.new(__FILE__, nil, 'EvilVFS') db.execute(<<-eosql) create table if not exists users(id integer primary key, name string) eosql 100.times { db.execute(<<-eosql, 'tenderlove') insert into users(name) values (?) eosql } p db.execute('select count(*) from users') __END__
  • 127. 3:
  • 131. • Ruby 1.9 • 1000 ( )
  • 132. require 'sqlite3' db = SQLite3::Database.new(':memory:') db.execute('CREATE TABLE foo(id INTEGER, name VARCHAR)') db.execute('INSERT INTO foo (id, name) VALUES (?,?)', [10,'hello world']) rows = db.execute('SELECT name FROM foo') p rows.first.first.encoding # => #<Encoding:UTF-8> Encoding.default_internal = 'EUC-JP' rows = db.execute('SELECT name FROM foo') p rows.first.first.encoding # => #<Encoding:EUC-JP>
  • 133. require 'sqlite3' db = SQLite3::Database.new(':memory:') db.execute('CREATE TABLE foo(id INTEGER, name VARCHAR)') db.execute('INSERT INTO foo (id, name) VALUES (?,?)', [10,'hello world']) rows = db.execute('SELECT name FROM foo') p rows.first.first.encoding # => #<Encoding:UTF-8> Encoding.default_internal = 'EUC-JP' rows = db.execute('SELECT name FROM foo') p rows.first.first.encoding # => #<Encoding:EUC-JP>
  • 134. require 'sqlite3' db = SQLite3::Database.new(':memory:') db.execute('CREATE TABLE foo(id INTEGER, name VARCHAR)') db.execute('INSERT INTO foo (id, name) VALUES (?,?)', [10,'hello world']) rows = db.execute('SELECT name FROM foo') p rows.first.first.encoding # => #<Encoding:UTF-8> Encoding.default_internal = 'EUC-JP' rows = db.execute('SELECT name FROM foo') p rows.first.first.encoding # => #<Encoding:EUC-JP>
  • 135. (SELECT ) 1.2.5 1.3.0 1000 100 10 1 0.1 0.01 500 1000 1500 2000 2500 3000 3500
  • 137. Phuby!
  • 138. Ruby.PHP() Phuby::Runtime.php do |rt| rt.eval('$v = strlen("PHP IS AWESOME");') puts rt['v'] # => 14 end
  • 139. Ruby.PHP() 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
  • 140. $PHP->Ruby(); class FUN def times puts "hello" end end Phuby::Runtime.php do |rt| rt['fun'] = FUN.new rt.eval('$fun->times();') # => hello end
  • 141. PHP
  • 147. Ruby C PHP Weak Proxy Reference PHP (runtime) Table Ruby
  • 148. Ruby C PHP Weak Proxy Reference PHP (runtime) Table Ruby
  • 149. PHP Ruby
  • 151. Ruby C PHP Weak Proxy Reference PHP (runtime) Table Ruby
  • 152. Ruby C PHP Weak Proxy Reference PHP (runtime) Table Ruby
  • 153. Ruby PHP
  • 155. Ruby C PHP Proxy Ruby PHP (runtime)
  • 156. Ruby C PHP Proxy Ruby PHP (runtime) Proxy (object)
  • 157. Phuby
  • 158. PHP + WEBrick = Blog
  • 160. #!/usr/bin/env ruby require 'rubygems' require 'phuby' require 'rack' ## # Rack::Phrack is a Rack handler that will evaulate and serve PHP files. class Rack::Phrack < Rack::File class Events < Struct.new(:code, :headers, :body) def write string; body << string; end def send_headers response_code; end def header value, op k, v = value.split(': ', 2) self.code = 302 if k == 'Location' headers[k] = [headers[k], Rack::Utils.unescape(v)].compact.join "n" 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)
  • 173. One Click Installer Luis Lavena