SlideShare una empresa de Scribd logo
1 de 175
Descargar para leer sin conexión
Have Fun
Programming
Programming for
      Fun!
@tenderlove
...
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
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/
•
•
•
•
Ruby
class
end
6.times {
            .new
}
Thread.new do
        .    ()
end
Thread.new do
      .    ()
end
(Thread.list -[Thread.main]).each
{ |x|
  x.join
}
• Ruby
•C
• Java
• Lisp
• PHP?
We Speak

•
•
•
•
.count


.count
;_;
";_;".encode(   ) # => ":'("
!
/
Ruby Brigades
Seattle.rb
Hack Night
!!!!
!
!
Hallway Track
•
•
•
•
•
• Rails 3
•
• XML
• YAML
0 bugs in Ruby 1.9
50% used Ruby 1.9
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
SQLite3-Ruby
SQLite3-Ruby

• SQLite3
• Jamis Buck
• SWIG
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
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:
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
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
#!/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
Special Thanks!
aka @masuidrive
zenspider
Special Request
One Click Installer




    Luis Lavena
Having Fun Programming!
Having Fun Programming!

Más contenido relacionado

La actualidad más candente

Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script ProgrammingLin 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 editionEleanor 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 editionosfameron
 
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 6garux
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perlgarux
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of RubyTom 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 zipperosfameron
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In PythonMarwan 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 PythonNicholas Tollervey
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2osfameron
 

La actualidad más candente (17)

Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
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
 
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
 
extending-php
extending-phpextending-php
extending-php
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 
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)
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
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
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In Python
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
An (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonAn (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to Python
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
 

Similar a Having Fun Programming!

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 ClojureDmitry Buzdin
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 
PHP Workshop Notes
PHP Workshop NotesPHP Workshop Notes
PHP Workshop NotesPamela 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 pm7Masahiro 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 SpaceMaarten 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 minutosEdgar Suarez
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & ToolsIan Barber
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingMuthu 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 frameworkChristian Trabold
 

Similar a 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
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
 
Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
PHP Workshop Notes
PHP Workshop NotesPHP Workshop Notes
PHP Workshop Notes
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
 
DataMapper
DataMapperDataMapper
DataMapper
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
 
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
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
비윈도우즈 환경의 기술 서적 번역 도구 경험 공유
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
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
 

Más de Aaron Patterson

Más de Aaron Patterson (7)

RubyConf Argentina 2011
RubyConf Argentina 2011RubyConf Argentina 2011
RubyConf Argentina 2011
 
Nordic Ruby 2011
Nordic Ruby 2011Nordic Ruby 2011
Nordic Ruby 2011
 
RailsConf 2011 Keynote
RailsConf 2011 KeynoteRailsConf 2011 Keynote
RailsConf 2011 Keynote
 
Behind the Curtain
Behind the CurtainBehind the Curtain
Behind the Curtain
 
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
 
RubyConf Brazil 2010
RubyConf Brazil 2010RubyConf Brazil 2010
RubyConf Brazil 2010
 
Worst. Ideas. Ever.
Worst. Ideas. Ever.Worst. Ideas. Ever.
Worst. Ideas. Ever.
 

Último

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 

Último (20)

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 

Having Fun Programming!

  • 1.
  • 5.
  • 6.
  • 7.
  • 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
  • 12.
  • 14. Q: How can I enjoy programming? http://www.flickr.com/photos/recompile_net/3733132232/
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22. Ruby
  • 23.
  • 24.
  • 25.
  • 26.
  • 28.
  • 29. Thread.new do . () end Thread.new do . () end (Thread.list -[Thread.main]).each { |x| x.join }
  • 30.
  • 31. • Ruby •C • Java • Lisp • PHP?
  • 32.
  • 33.
  • 36. ;_; ";_;".encode( ) # => ":'("
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42. !
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49. /
  • 50.
  • 51.
  • 52.
  • 53.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61. !!!!
  • 62. !
  • 63. !
  • 64.
  • 66.
  • 67.
  • 68.
  • 70. • Rails 3 • • XML • YAML
  • 71. 0 bugs in Ruby 1.9
  • 73.
  • 74.
  • 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
  • 102.
  • 103.
  • 104.
  • 107.
  • 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
  • 113.
  • 114.
  • 115.
  • 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:
  • 128.
  • 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
  • 142.
  • 143.
  • 144.
  • 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
  • 159.
  • 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)
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 173. One Click Installer Luis Lavena