SlideShare uma empresa Scribd logo
1 de 43
Baixar para ler offline
Code Reading 101
TWO THINGS TO
KNOW ABOUT ME


I wrote the TextMate book

My name is Jim Weirich
JAMES EDWARD
GRAY II
I wrote two books for the Pragmatic Programmers: Best of
Ruby Quiz and TextMate: Power Editing for the Mac

I’ve contributed documentation and patches for some
standard libraries, which I now help to maintain

I built FasterCSV (now CSV), HighLine (with Greg), Elif, and
a few other libraries people don’t use

I created the Ruby Quiz and ran it for the first three years
HI. I’M JAMES AND
   I READ CODE.
HOW MUCH SHOULD
   YOU READ?
                      0%   25%        50%         75%
                                                                  100%
          Novice
Advanced Beginner
       Competent
         Proficient
            Expert




    My opinion based on the Dreyfus Model of Skill Acquisition.
WHY IS CODE
READING IMPORTANT?
It can show you common idioms

It’s good to practice breaking down possibly challenging
code, because you will always have to work with other’s code

Understanding how something works gives you insight into
any limitations it has

Seeing bad code helps you write better code

Knowledge workers always need more ideas
INTRODUCING
 RESTCLIENT
WHAT IS RESTCLIENT?


Sinatra’s sister library (sometimes called “reverse Sinatra”)

It provides a very clean interface to RESTful web services

Simple well-written code (around 500 lines of clear code for
the core functionality)

Plus a couple of exciting features
require quot;rubygemsquot;
require quot;rest_clientquot;
require quot;jsonquot;

twitter = RestClient::Resource.new( quot;http://twitter.com/statusesquot;,
                                    :user     => quot;JEG2quot;,
                                    :password => quot;secretquot; )

json    = twitter[quot;friends_timeline.jsonquot;].get
tweets = JSON.parse(json)
tweets.each do |tweet|
  # ...
end




               BASIC GET
      Reading tweets with Twitter’s API
require quot;rubygemsquot;
require quot;rest_clientquot;
require quot;jsonquot;

twitter = RestClient::Resource.new( quot;http://twitter.com/statusesquot;,
                                    :user     => quot;JEG2quot;,
                                    :password => quot;secretquot; )

json    = twitter[quot;update.jsonquot;].post(:status => quot;Hello from #mwrc!quot;)
tweet   = JSON.parse(json)
# ...




              BASIC POST
        Posting a tweet with Twitter’s API
NETWORKING CODE
   DONE RIGHT
def process_result(res)
                                                       if res.code =~ /A2d{2}z/
                                                         decode res['content-encoding'], res.body if res.body
                                                       elsif %w(301 302 303).include? res.code
                                                         url = res.header['Location']
def transmit(uri, req, payload)
  setup_credentials(req)                                 if url !~ /^http/
                                                           uri = URI.parse(@url)
 net = net_http_class.new(uri.host, uri.port)              uri.path = quot;/#{url}quot;.squeeze('/')
 net.use_ssl = uri.is_a?(URI::HTTPS)                       url = uri.to_s
 net.verify_mode = OpenSSL::SSL::VERIFY_NONE             end
 net.read_timeout = @timeout if @timeout
 net.open_timeout = @open_timeout if @open_timeout       raise Redirect, url
                                                       elsif res.code == quot;304quot;
 display_log request_log                                 raise NotModified, res
                                                       elsif res.code == quot;401quot;
 net.start do |http|                                     raise Unauthorized, res
   res = http.request(req, payload)                    elsif res.code == quot;404quot;
   display_log response_log(res)                         raise ResourceNotFound, res
   string = process_result(res)                        else
                                                         raise RequestFailed, res
    if string or @method == :head                      end
      Response.new(string, res)                      end
    else
      nil
    end
  end
rescue EOFError
                                                     def decode(content_encoding, body)
  raise RestClient::ServerBrokeConnection
                                                       if content_encoding == 'gzip' and not body.empty?
rescue Timeout::Error
                                                         Zlib::GzipReader.new(StringIO.new(body)).read
  raise RestClient::RequestTimeout
                                                       elsif content_encoding == 'deflate'
end
                                                         Zlib::Inflate.new.inflate(body)
                                                       else
                                                         body
                                                       end
                                                     end
A RESTFUL SHELL
   (IN 90 LOC)
$ restclient 
> get http://twitter.com/statuses/friends_timeline.json?count=1 
> JEG2 secret
[{quot;textquot;:quot;Sent out first round of Twitter client betas…quot;,
  quot;userquot;:{quot;namequot;:quot;Jeremy McAnallyquot;,quot;screen_namequot;:quot;jeremymcanallyquot;,…},
  …}]




CURL-ISH REQUESTS
 Fetching the latest tweet !om Twitter’s API
$ restclient http://twitter.com/statuses JEG2 secret
>> post quot;update.jsonquot;, :status => quot;The RestClient shell is fun.quot;
=> quot;{quot;textquot;:quot;The RestClient shell is fun.quot;,…}quot;
>> get quot;friends_timeline.json?count=1quot;
=> quot;[{quot;textquot;:quot;The RestClient shell is fun.quot;,…}]quot;




         RESTFUL IRB
       Interacting with the Twitter API
LOGGING IN RUBY
$ RESTCLIENT_LOG=twitter_fun.rb restclient …
    >> post quot;update.jsonquot;, :status => quot;The RestClient shell is fun.quot;
    => …
    >> get quot;friends_timeline.json?count=1quot;
    => …



# twitter_fun.rb
RestClient.post quot;http://twitter.com/statuses/update.jsonquot;,
                 quot;status=The%20RestClient%20shell%20is%20fun.quot;,
                 :content_type=>quot;application/x-www-form-urlencodedquot;
# => 200 OK | application/json 379 bytes
RestClient.get quot;http://twitter.com/statuses/friends_timeline.json?count=1quot;
# => 200 OK | application/json 381 bytes




   GENERATING RUBY
  Interactively building a RESTful Ruby script
FASTERCSV IS
THE NEW CSV
THE LESS BORING
PARTS OF CSV
Tricky data structures are needed

  Rows need ordered access for their columns

  Users also like to work with them by header name

  Column names often repeat

Now that we have m17n, CSV parses in the encoding of your
data (no transcoding is done on your data)
THE ARRAY-HASH-
WITH-DUPLICATES
  DATA THING
require quot;csvquot;   # using Ruby 1.9

data = <<END_DATA
Console,Units Sold 2007,Percent,Units Sold 2008,Percent
Wii,quot;719,141quot;,49.4%,quot;1,184,651quot;,49.6%
XBox 360,quot;333,084quot;,22.9%,quot;743,976quot;,31.1%
PlayStation 3,quot;404,900quot;,27.8%,quot;459,777quot;,19.3%
END_DATA
ps3 = CSV.parse(data, :headers => true, :header_converters => :symbol)[-1]

ps3[0]                                       #   =>   quot;PlayStation 3quot;
ps3[:percent]                                #   =>   quot;27.8%quot;
ps3[:percent, 3]                             #   =>   quot;19.3%quot;
ps3[:percent, ps3.index(:units_sold_2008)]   #   =>   quot;19.3%quot;




                    CSV::ROW
           The various ways to refer to data
M17N IN ACTION
@io       =   if data.is_a? String then StringIO.new(data) else data end
@encoding =   if @io.respond_to? :internal_encoding
                @io.internal_encoding || @io.external_encoding
              elsif @io.is_a? StringIO
                @io.string.encoding
              end
@encoding ||= Encoding.default_internal || Encoding.default_external


def encode_re(*chunks)
  Regexp.new(encode_str(*chunks))
end

def encode_str(*chunks)
  chunks.map { |chunk| chunk.encode(@encoding.name) }.join
end


sample = read_to_char(1024)
sample += read_to_char(1) if sample[-1..-1] == encode_str(quot;rquot;) and
                             not @io.eof?

if sample =~ encode_re(quot;rn?|nquot;)
  @row_sep = $&
  break
end
OTHER POINTS
OF INTEREST
The parser

  Ruby 1.9’s CSV library uses primarily one ugly regular
  expression from Master Regular Expressions

  The old FasterCSV has switched to a non-regex parser to
  dodge some regex engine weaknesses

FasterCSV::Table is another interesting data structure that
can work in columns or rows
BJ, SLAVE,
AND TERMINATOR
WHY THESE
LIBRARIES?
They teach how to build multiprocessing Unix software

  Covers Thread and fork(), apart and together

  Using pipes

  Signal handling

  And much more

Robust code written by an expert
HOW TO ASK YOUR
CHILD TO KILL YOU
def terminate options = {}, &block
  options = { :seconds => Float(options).to_i } unless Hash === options

 seconds = getopt :seconds, options
 trap = getopt :trap, options,
   lambda{ eval(quot;raise(::Terminator::Error, '#{ seconds }s')quot;, block) }

 handler = Signal.trap(signal, &trap)

 plot_to_kill pid, :in => seconds, :with => signal

  begin
    block.call
  ensure
    Signal.trap(signal, handler)
  end
end
def plot_to_kill pid, options = {}
  seconds = getopt :in, options
  signal = getopt :with, options
  process.puts [pid, seconds, signal].join(' ')
  process.flush
end


fattr :process do
  process = IO.popen quot;#{ ruby } #{ program.inspect }quot;, 'w+'
  at_exit do
    begin
      Process.kill -9, process.pid
    rescue Object
    end
  end
  process.sync = true
  process
end
fattr :program do
  code = <<-code
    while(( line = STDIN.gets ))
      pid, seconds, signal, *ignored = line.strip.split

     pid = Float(pid).to_i
     seconds = Float(seconds)
     signal = Float(signal).to_i rescue String(signal)

     sleep seconds

      begin
        Process.kill signal, pid
      rescue Object
      end
    end
  code
  tmp = Tempfile.new quot;#{ ppid }-#{ pid }-#{ rand }quot;
  tmp.write code
  tmp.close
  tmp.path
end
OTHER POINTS
OF INTEREST
bj – A robust background priority queue for Rails

  Noticing changes from the outside world via signals

  Managing and monitoring an external job

slave – Trivial multiprocessing with built-in IPC

  How to set up a “heartbeat” between processes

  How to run DRb over Unix domain sockets
THE ART OF
CODE READING
PROCESS TIPS

Take a deep breath and relax

  Not all code sucks

Don’t start with Rails

  There’s a ton of great stuff in there

  But it’s a big and complex beast

Have a goal
GETTING THE CODE


gem unpack GEM_NAME

Use anonymous VCS access to pull a local copy of the code

Open it in your standard environment as you would if you
were going to edit it
FINDING THINGS
Try the conventions first

  Executables are probably in the bin/ directory

  Look for MyModule::MyClass in lib/my_module/
  my_class.rb

  Look for methods in super classes and mixed in modules

But remember Ruby is quite dynamic

  Hunt for some “core extensions”
UNDERSTANDING
THE CODE

Start with the tests/specs if there are any

Check for an “examples/” directory

Try to load and play with certain classes in isolation

  irb -r a_class_to_play_with

Remember Ruby’s reflection methods, like methods()
QUESTIONS?
About code or other important topics…

Mais conteúdo relacionado

Mais procurados

Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalKent Ohashi
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rackdanwrong
 
Jersey framework
Jersey frameworkJersey framework
Jersey frameworkknight1128
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Java web programming
Java web programmingJava web programming
Java web programmingChing Yi Chan
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to NodejsGabriele Lana
 
"The little big project. From zero to hero in two weeks with 3 front-end engi...
"The little big project. From zero to hero in two weeks with 3 front-end engi..."The little big project. From zero to hero in two weeks with 3 front-end engi...
"The little big project. From zero to hero in two weeks with 3 front-end engi...Fwdays
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby CoreHiroshi SHIBATA
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsMark Baker
 
An Introduction to Solr
An Introduction to SolrAn Introduction to Solr
An Introduction to Solrtomhill
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with JasmineLeon van der Grient
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 

Mais procurados (20)

groovy & grails - lecture 2
groovy & grails - lecture 2groovy & grails - lecture 2
groovy & grails - lecture 2
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 
Rest in flask
Rest in flaskRest in flask
Rest in flask
 
8 Minutes On Rack
8 Minutes On Rack8 Minutes On Rack
8 Minutes On Rack
 
Jersey framework
Jersey frameworkJersey framework
Jersey framework
 
Ruby HTTP clients
Ruby HTTP clientsRuby HTTP clients
Ruby HTTP clients
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Java web programming
Java web programmingJava web programming
Java web programming
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to Nodejs
 
"The little big project. From zero to hero in two weeks with 3 front-end engi...
"The little big project. From zero to hero in two weeks with 3 front-end engi..."The little big project. From zero to hero in two weeks with 3 front-end engi...
"The little big project. From zero to hero in two weeks with 3 front-end engi...
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
 
An Introduction to Solr
An Introduction to SolrAn Introduction to Solr
An Introduction to Solr
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
httpie
httpiehttpie
httpie
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 

Semelhante a Little Big Ruby

And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportBen Scofield
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPMariano Iglesias
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxDr Nic Williams
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous MerbMatt Todd
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonManageIQ
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairMark
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun..."ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...Julia Cherniak
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialYi-Ting Cheng
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important PartsSergey Bolshchikov
 
Developing node-mdb: a Node.js - based clone of SimpleDB
Developing node-mdb: a Node.js - based clone of SimpleDBDeveloping node-mdb: a Node.js - based clone of SimpleDB
Developing node-mdb: a Node.js - based clone of SimpleDBRob Tweed
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Benjamin Bock
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and PythonPiXeL16
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimizationxiaojueqq12345
 

Semelhante a Little Big Ruby (20)

And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous Merb
 
Node.js - A Quick Tour
Node.js - A Quick TourNode.js - A Quick Tour
Node.js - A Quick Tour
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
Headless Js Testing
Headless Js TestingHeadless Js Testing
Headless Js Testing
 
A Life of breakpoint
A Life of breakpointA Life of breakpoint
A Life of breakpoint
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun..."ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
 
Developing node-mdb: a Node.js - based clone of SimpleDB
Developing node-mdb: a Node.js - based clone of SimpleDBDeveloping node-mdb: a Node.js - based clone of SimpleDB
Developing node-mdb: a Node.js - based clone of SimpleDB
 
Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)Ruby Topic Maps Tutorial (2007-10-10)
Ruby Topic Maps Tutorial (2007-10-10)
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Web program-peformance-optimization
Web program-peformance-optimizationWeb program-peformance-optimization
Web program-peformance-optimization
 

Mais de LittleBIGRuby

Wii Ruby All Work And No Play Just Wont Do
Wii Ruby All Work And No Play Just Wont DoWii Ruby All Work And No Play Just Wont Do
Wii Ruby All Work And No Play Just Wont DoLittleBIGRuby
 
The Building Blocks Of Modularity
The Building Blocks Of ModularityThe Building Blocks Of Modularity
The Building Blocks Of ModularityLittleBIGRuby
 
Outside In Development With Cucumber
Outside In Development With CucumberOutside In Development With Cucumber
Outside In Development With CucumberLittleBIGRuby
 
Outside-In Development with Cucumber
Outside-In Development with CucumberOutside-In Development with Cucumber
Outside-In Development with CucumberLittleBIGRuby
 
La Dolce Vita Rubyista
La Dolce Vita RubyistaLa Dolce Vita Rubyista
La Dolce Vita RubyistaLittleBIGRuby
 
Practical Puppet Systems Building Systems 1
Practical Puppet Systems Building Systems 1Practical Puppet Systems Building Systems 1
Practical Puppet Systems Building Systems 1LittleBIGRuby
 
Compiling And Optimizing Scripting Languages
Compiling And Optimizing Scripting LanguagesCompiling And Optimizing Scripting Languages
Compiling And Optimizing Scripting LanguagesLittleBIGRuby
 

Mais de LittleBIGRuby (9)

Wii Ruby All Work And No Play Just Wont Do
Wii Ruby All Work And No Play Just Wont DoWii Ruby All Work And No Play Just Wont Do
Wii Ruby All Work And No Play Just Wont Do
 
The Building Blocks Of Modularity
The Building Blocks Of ModularityThe Building Blocks Of Modularity
The Building Blocks Of Modularity
 
Outside In Development With Cucumber
Outside In Development With CucumberOutside In Development With Cucumber
Outside In Development With Cucumber
 
Outside-In Development with Cucumber
Outside-In Development with CucumberOutside-In Development with Cucumber
Outside-In Development with Cucumber
 
La Dolce Vita Rubyista
La Dolce Vita RubyistaLa Dolce Vita Rubyista
La Dolce Vita Rubyista
 
Practical Puppet Systems Building Systems 1
Practical Puppet Systems Building Systems 1Practical Puppet Systems Building Systems 1
Practical Puppet Systems Building Systems 1
 
Compiling And Optimizing Scripting Languages
Compiling And Optimizing Scripting LanguagesCompiling And Optimizing Scripting Languages
Compiling And Optimizing Scripting Languages
 
Ffi
FfiFfi
Ffi
 
Sequel
SequelSequel
Sequel
 

Último

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 

Último (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 

Little Big Ruby

  • 2. TWO THINGS TO KNOW ABOUT ME I wrote the TextMate book My name is Jim Weirich
  • 3. JAMES EDWARD GRAY II I wrote two books for the Pragmatic Programmers: Best of Ruby Quiz and TextMate: Power Editing for the Mac I’ve contributed documentation and patches for some standard libraries, which I now help to maintain I built FasterCSV (now CSV), HighLine (with Greg), Elif, and a few other libraries people don’t use I created the Ruby Quiz and ran it for the first three years
  • 4.
  • 5.
  • 6. HI. I’M JAMES AND I READ CODE.
  • 7. HOW MUCH SHOULD YOU READ? 0% 25% 50% 75% 100% Novice Advanced Beginner Competent Proficient Expert My opinion based on the Dreyfus Model of Skill Acquisition.
  • 8. WHY IS CODE READING IMPORTANT? It can show you common idioms It’s good to practice breaking down possibly challenging code, because you will always have to work with other’s code Understanding how something works gives you insight into any limitations it has Seeing bad code helps you write better code Knowledge workers always need more ideas
  • 9.
  • 11. WHAT IS RESTCLIENT? Sinatra’s sister library (sometimes called “reverse Sinatra”) It provides a very clean interface to RESTful web services Simple well-written code (around 500 lines of clear code for the core functionality) Plus a couple of exciting features
  • 12. require quot;rubygemsquot; require quot;rest_clientquot; require quot;jsonquot; twitter = RestClient::Resource.new( quot;http://twitter.com/statusesquot;, :user => quot;JEG2quot;, :password => quot;secretquot; ) json = twitter[quot;friends_timeline.jsonquot;].get tweets = JSON.parse(json) tweets.each do |tweet| # ... end BASIC GET Reading tweets with Twitter’s API
  • 13. require quot;rubygemsquot; require quot;rest_clientquot; require quot;jsonquot; twitter = RestClient::Resource.new( quot;http://twitter.com/statusesquot;, :user => quot;JEG2quot;, :password => quot;secretquot; ) json = twitter[quot;update.jsonquot;].post(:status => quot;Hello from #mwrc!quot;) tweet = JSON.parse(json) # ... BASIC POST Posting a tweet with Twitter’s API
  • 14. NETWORKING CODE DONE RIGHT
  • 15. def process_result(res) if res.code =~ /A2d{2}z/ decode res['content-encoding'], res.body if res.body elsif %w(301 302 303).include? res.code url = res.header['Location'] def transmit(uri, req, payload) setup_credentials(req) if url !~ /^http/ uri = URI.parse(@url) net = net_http_class.new(uri.host, uri.port) uri.path = quot;/#{url}quot;.squeeze('/') net.use_ssl = uri.is_a?(URI::HTTPS) url = uri.to_s net.verify_mode = OpenSSL::SSL::VERIFY_NONE end net.read_timeout = @timeout if @timeout net.open_timeout = @open_timeout if @open_timeout raise Redirect, url elsif res.code == quot;304quot; display_log request_log raise NotModified, res elsif res.code == quot;401quot; net.start do |http| raise Unauthorized, res res = http.request(req, payload) elsif res.code == quot;404quot; display_log response_log(res) raise ResourceNotFound, res string = process_result(res) else raise RequestFailed, res if string or @method == :head end Response.new(string, res) end else nil end end rescue EOFError def decode(content_encoding, body) raise RestClient::ServerBrokeConnection if content_encoding == 'gzip' and not body.empty? rescue Timeout::Error Zlib::GzipReader.new(StringIO.new(body)).read raise RestClient::RequestTimeout elsif content_encoding == 'deflate' end Zlib::Inflate.new.inflate(body) else body end end
  • 16. A RESTFUL SHELL (IN 90 LOC)
  • 17. $ restclient > get http://twitter.com/statuses/friends_timeline.json?count=1 > JEG2 secret [{quot;textquot;:quot;Sent out first round of Twitter client betas…quot;, quot;userquot;:{quot;namequot;:quot;Jeremy McAnallyquot;,quot;screen_namequot;:quot;jeremymcanallyquot;,…}, …}] CURL-ISH REQUESTS Fetching the latest tweet !om Twitter’s API
  • 18. $ restclient http://twitter.com/statuses JEG2 secret >> post quot;update.jsonquot;, :status => quot;The RestClient shell is fun.quot; => quot;{quot;textquot;:quot;The RestClient shell is fun.quot;,…}quot; >> get quot;friends_timeline.json?count=1quot; => quot;[{quot;textquot;:quot;The RestClient shell is fun.quot;,…}]quot; RESTFUL IRB Interacting with the Twitter API
  • 20. $ RESTCLIENT_LOG=twitter_fun.rb restclient … >> post quot;update.jsonquot;, :status => quot;The RestClient shell is fun.quot; => … >> get quot;friends_timeline.json?count=1quot; => … # twitter_fun.rb RestClient.post quot;http://twitter.com/statuses/update.jsonquot;, quot;status=The%20RestClient%20shell%20is%20fun.quot;, :content_type=>quot;application/x-www-form-urlencodedquot; # => 200 OK | application/json 379 bytes RestClient.get quot;http://twitter.com/statuses/friends_timeline.json?count=1quot; # => 200 OK | application/json 381 bytes GENERATING RUBY Interactively building a RESTful Ruby script
  • 21.
  • 23. THE LESS BORING PARTS OF CSV Tricky data structures are needed Rows need ordered access for their columns Users also like to work with them by header name Column names often repeat Now that we have m17n, CSV parses in the encoding of your data (no transcoding is done on your data)
  • 25. require quot;csvquot; # using Ruby 1.9 data = <<END_DATA Console,Units Sold 2007,Percent,Units Sold 2008,Percent Wii,quot;719,141quot;,49.4%,quot;1,184,651quot;,49.6% XBox 360,quot;333,084quot;,22.9%,quot;743,976quot;,31.1% PlayStation 3,quot;404,900quot;,27.8%,quot;459,777quot;,19.3% END_DATA ps3 = CSV.parse(data, :headers => true, :header_converters => :symbol)[-1] ps3[0] # => quot;PlayStation 3quot; ps3[:percent] # => quot;27.8%quot; ps3[:percent, 3] # => quot;19.3%quot; ps3[:percent, ps3.index(:units_sold_2008)] # => quot;19.3%quot; CSV::ROW The various ways to refer to data
  • 27. @io = if data.is_a? String then StringIO.new(data) else data end @encoding = if @io.respond_to? :internal_encoding @io.internal_encoding || @io.external_encoding elsif @io.is_a? StringIO @io.string.encoding end @encoding ||= Encoding.default_internal || Encoding.default_external def encode_re(*chunks) Regexp.new(encode_str(*chunks)) end def encode_str(*chunks) chunks.map { |chunk| chunk.encode(@encoding.name) }.join end sample = read_to_char(1024) sample += read_to_char(1) if sample[-1..-1] == encode_str(quot;rquot;) and not @io.eof? if sample =~ encode_re(quot;rn?|nquot;) @row_sep = $& break end
  • 28. OTHER POINTS OF INTEREST The parser Ruby 1.9’s CSV library uses primarily one ugly regular expression from Master Regular Expressions The old FasterCSV has switched to a non-regex parser to dodge some regex engine weaknesses FasterCSV::Table is another interesting data structure that can work in columns or rows
  • 29.
  • 31. WHY THESE LIBRARIES? They teach how to build multiprocessing Unix software Covers Thread and fork(), apart and together Using pipes Signal handling And much more Robust code written by an expert
  • 32. HOW TO ASK YOUR CHILD TO KILL YOU
  • 33. def terminate options = {}, &block options = { :seconds => Float(options).to_i } unless Hash === options seconds = getopt :seconds, options trap = getopt :trap, options, lambda{ eval(quot;raise(::Terminator::Error, '#{ seconds }s')quot;, block) } handler = Signal.trap(signal, &trap) plot_to_kill pid, :in => seconds, :with => signal begin block.call ensure Signal.trap(signal, handler) end end
  • 34. def plot_to_kill pid, options = {} seconds = getopt :in, options signal = getopt :with, options process.puts [pid, seconds, signal].join(' ') process.flush end fattr :process do process = IO.popen quot;#{ ruby } #{ program.inspect }quot;, 'w+' at_exit do begin Process.kill -9, process.pid rescue Object end end process.sync = true process end
  • 35. fattr :program do code = <<-code while(( line = STDIN.gets )) pid, seconds, signal, *ignored = line.strip.split pid = Float(pid).to_i seconds = Float(seconds) signal = Float(signal).to_i rescue String(signal) sleep seconds begin Process.kill signal, pid rescue Object end end code tmp = Tempfile.new quot;#{ ppid }-#{ pid }-#{ rand }quot; tmp.write code tmp.close tmp.path end
  • 36. OTHER POINTS OF INTEREST bj – A robust background priority queue for Rails Noticing changes from the outside world via signals Managing and monitoring an external job slave – Trivial multiprocessing with built-in IPC How to set up a “heartbeat” between processes How to run DRb over Unix domain sockets
  • 37.
  • 38. THE ART OF CODE READING
  • 39. PROCESS TIPS Take a deep breath and relax Not all code sucks Don’t start with Rails There’s a ton of great stuff in there But it’s a big and complex beast Have a goal
  • 40. GETTING THE CODE gem unpack GEM_NAME Use anonymous VCS access to pull a local copy of the code Open it in your standard environment as you would if you were going to edit it
  • 41. FINDING THINGS Try the conventions first Executables are probably in the bin/ directory Look for MyModule::MyClass in lib/my_module/ my_class.rb Look for methods in super classes and mixed in modules But remember Ruby is quite dynamic Hunt for some “core extensions”
  • 42. UNDERSTANDING THE CODE Start with the tests/specs if there are any Check for an “examples/” directory Try to load and play with certain classes in isolation irb -r a_class_to_play_with Remember Ruby’s reflection methods, like methods()
  • 43. QUESTIONS? About code or other important topics…