SlideShare ist ein Scribd-Unternehmen logo
1 von 43
Downloaden Sie, um offline zu lesen
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…

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
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
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
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
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
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
 
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
 
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
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
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
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 

Kürzlich hochgeladen (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
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
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
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
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
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
 
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
 
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
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
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
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.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…