SlideShare ist ein Scribd-Unternehmen logo
1 von 187
Downloaden Sie, um offline zu lesen
HELLO!!!
ZOMG HAPPY
 SATURDAY!
PEW PEW PEW~!!!
Aaron Patterson
@tenderlove
google 'tenderlove'
      Might be NSFW
AT&T, AT&T logo and all AT&T related marks are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies.
Enterprise
       Developer
http://github.com/tenderlove/enterprise
ruby core
committer
rails core
committer
rails
committer
My Failures
rails core
committer
rails
committer
Presenting Last
I like Ryan Davis
My Slides Suck
    (Sorry Shane)
minitest
RFC 2119
 common.rspec
No Parens on
Method Definitions
def foo bar, baz
  ...
end
Ruby + JavaScript
Ruby + C
My Failures
  (as a presenter)
Fun
Practical
I am a nerd
I like boring things
2 Presentations
Practical
Fun!
The Fun
Your Guide to
Presentation
 Popularity!
Your Guide to
Presentation
  Notoriety!
•Provocative Title
• Risqué Photos

•Ruby Code?
Provocative Title:
Use Ruby 1.9 like an
     Engineer
Use Ruby 1.9 like a
 SEXY Engineer
Risqué Photos
America's Next Top
      Model
America's Next Top
    Engineer
Confident
Elegant
Sultry
Sexy
Thoughtful
Fierce
Playful
Powerful
Provocative
Ruby Code?
protected

    def method_missing(method, *args, &block)
      if Array.method_defined?(method)
        to_a.send(method, *args, &block)
      elsif @klass.scopes[method]
        merge(@klass.send(method, *args, &block))
      elsif @klass.respond_to?(method)
        scoping { @klass.send(method, *args, &block) }
      elsif arel.respond_to?(method)
        arel.send(method, *args, &block)
      elsif match = DynamicFinderMatch.match(method)
        attributes = match.attribute_names
        super unless @klass.send(:all_attributes_exists?, attributes)

        if match.finder?
           find_by_attributes(match, attributes, *args)
        elsif match.instantiator?
           find_or_instantiator_by_attributes(match, attributes, *args, &block)
        end
      else
        super
      end
    end

    private

    def references_eager_loaded_tables?
      # always convert table names to downcase as in Oracle quoted table names are in uppercase
      joined_tables = (tables_in_string(arel.joins(arel)) + [table.name, table.table_alias]).compact.map{ |t|
t.downcase }.uniq
      (tables_in_string(to_sql) - joined_tables).any?
    end
TL;DR
The Practical
Hidden Gems of
   Ruby 1.9
Ruby 1.9 PSA
minitest
require 'minitest/autorun'

class FooTest < MiniTest::Unit::TestCase
  WIN32 = true

 def test_foo
   assert_equal 'foo', 'foo'
 end

 def test_refutation
   refute_equal 'foo', 'bar'
 end

  def test_skip
    return skip if WIN32
    assert_equal 'fun!', 'fun!'
  end
end
require 'minitest/autorun'
Test::Unit::TestCase
           =>
MiniTest::Unit::TestCase
class FooTest < MiniTest::Unit::TestCase
end
assert_not_*
     =>
  refute_*
def test_refutation
  refute_equal 'foo', 'bar'
end
skip
class FooTest < MiniTest::Unit::TestCase
  WIN32 = true

  def test_skip
    skip if WIN32
    assert_equal 'fun!', 'fun!'
  end
end
Loaded suite footest
Started
.S.
Finished in 0.000682 seconds.

  1) Skipped:
test_skip(FooTest) [footest.rb:15]:
Skipped, no message given

3 tests, 2 assertions, 0 failures, 0 errors, 1 skips
randomization
class FailTest < MiniTest::Unit::TestCase
  @@foos = %w{ hello }

 def test_equality
   assert_equal @@foos, %w{ hello }
 end

  def test_append
    @@foos << "world"
    assert_equal @@foos, %w{ hello world }
  end
end
Test run options: --seed 31149

Loaded suite failtest
Started
..
Finished in 0.000604 seconds.

2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 31149
Test run options: --seed 29650

Loaded suite failtest
Started
.F
Finished in 0.000637 seconds.

  1) Failure:
test_equality(FailTest) [failtest.rb:7]:
Expected ["hello", "world"], not ["hello"].

2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

Test run options: --seed 29650
Test run options: --seed 29650

Loaded suite failtest
Started
.F
Finished in 0.000637 seconds.

  1) Failure:
test_equality(FailTest) [failtest.rb:7]:
Expected ["hello", "world"], not ["hello"].

2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

Test run options: --seed 29650
--seed 29650
-v
ruby failtest.rb --seed 29650 -v
Test run options: --seed 29650 --verbose

Loaded suite failtest
Started
FailTest#test_append: 0.00 s: .
FailTest#test_equality: 0.00 s: F

Finished in 0.000735 seconds.

  1) Failure:
test_equality(FailTest) [failtest.rb:7]:
Expected ["hello", "world"], not ["hello"].

2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

Test run options: --seed 29650 --verbose
Test run options: --seed 29650 --verbose

Loaded suite failtest
Started
FailTest#test_append: 0.00 s: .
FailTest#test_equality: 0.00 s: F

Finished in 0.000735 seconds.

  1) Failure:
test_equality(FailTest) [failtest.rb:7]:
Expected ["hello", "world"], not ["hello"].

2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

Test run options: --seed 29650 --verbose
Test Performance
class FooTest < MiniTest::Unit::TestCase
  def test_foo
    assert_equal 'foo', 'foo'
  end

 def test_refutation
   refute_equal 'foo', 'bar'
 end

  def test_slow
    sleep 10
  end
end
class FooTest < MiniTest::Unit::TestCase
  def test_foo
    assert_equal 'foo', 'foo'
  end

 def test_refutation
   refute_equal 'foo', 'bar'
 end

  def test_slow
    sleep 10
  end
end
Test run options: --seed 33095 --verbose

Loaded suite footest
Started
FooTest#test_slow: 10.00 s: .
FooTest#test_refutation: 0.00 s: .
FooTest#test_foo: 0.00 s: .

Finished in 10.001114 seconds.

3 tests, 2 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 33095 --verbose
Test run options: --seed 33095 --verbose

Loaded suite footest
Started
FooTest#test_slow: 10.00 s: .
FooTest#test_refutation: 0.00 s: .
FooTest#test_foo: 0.00 s: .

Finished in 10.001114 seconds.

3 tests, 2 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 33095 --verbose
With Rake:
rake test TESTSOPTS='-v'
rspec
describe 'Awesome' do
  describe 'Class' do
    it 'discovers something AMAZING' do
      (10 + 10).must_equal 20
    end

    it 'matches something AMAZING' do
      "vuvuzela".must_match /vuvu/
    end

    it 'raises something AMAZING' do
      lambda { raise }.must_raise(RuntimeError)
    end
  end
end
rspec
minitest/spec
require 'minitest/spec'
require 'minitest/autorun'
require 'minitest/spec'
require 'minitest/autorun'

describe 'Awesome' do
  describe 'Class' do
    it 'discovers something AMAZING' do
      (10 + 10).must_equal 20
    end

    it 'matches something AMAZING' do
      "vuvuzela".must_match /vuvu/
    end

    it 'must raise something' do
      lambda { raise }.must_raise(RuntimeError)
    end
  end
end
ObjectSpace
ObjectSpace.each_object do |obj|
  p obj
end
require 'objspace'

• count_objects_size
• memsize_of
• count_nodes
• count_tdata_objects
count_object_size
require 'objspace'

hash = {}
ObjectSpace.count_objects_size(hash)
p hash # =>
{:T_CLASS=>291520, :T_MODULE=>42512,
:T_STRING=>26133, :T_REGEXP=>11501,
:T_ARRAY=>5896, :T_HASH=>1088, :T_FILE=>9056,
:T_DATA=>1144348, :TOTAL=>1532054}
count_object_size
require 'objspace'

hash = {}
ObjectSpace.count_objects_size(hash)
p hash # =>
{:T_CLASS=>291520, :T_MODULE=>42512,
:T_STRING=>26133, :T_REGEXP=>11501,
:T_ARRAY=>5896, :T_HASH=>1088, :T_FILE=>9056,
:T_DATA=>1144348, :TOTAL=>1532054}
memsize_of


require 'objspace'
require 'fiddle'

cl = Fiddle::Closure.new(0, [1])
p ObjectSpace.memsize_of(cl) # => 232
memsize_of


require 'objspace'
require 'fiddle'

cl = Fiddle::Closure.new(0, [1])
p ObjectSpace.memsize_of(cl) # => 232
Implementation
struct rb_data_type_struct

struct rb_data_type_struct {
    const char *wrap_struct_name;
    struct {
   void (*dmark)(void*);
   void (*dfree)(void*);
   size_t (*dsize)(const void *);
   void *reserved[2]; /* For future extension.
                This array *must* be filled with ZERO. */
    } function;
    const rb_data_type_t *parent;
    void *data;        /* This area can be used for any purpose
                          by a programmer who define the type. */
};
struct rb_data_type_struct

struct rb_data_type_struct {
    const char *wrap_struct_name;
    struct {
   void (*dmark)(void*);
   void (*dfree)(void*);
   size_t (*dsize)(const void *);
   void *reserved[2]; /* For future extension.
                This array *must* be filled with ZERO. */
    } function;
    const rb_data_type_t *parent;
    void *data;        /* This area can be used for any purpose
                          by a programmer who define the type. */
};
static size_t my_memsize(const void *p) {
    return 10;
}

const rb_data_type_t my_data_type = {
    "my_extension",
    {NULL, NULL, my_memsize,},
};

static VALUE allocate(VALUE klass) {
    struct something * cif;
    return TypedData_Make_Struct(
      klass, something, &my_data_type, cif);
}
count_nodes


require 'objspace'

p ObjectSpace.count_nodes #=>
{:NODE_SCOPE=>50, :NODE_BLOCK=>168,
:NODE_IF=>27, :NODE_ITER=>7, ... }
count_nodes


require 'objspace'

p ObjectSpace.count_nodes #=>
{:NODE_SCOPE=>50, :NODE_BLOCK=>168,
:NODE_IF=>27, :NODE_ITER=>7, ... }
count_nodes

require 'objspace'

10.times do
  p ObjectSpace.count_nodes[:NODE_IF]
  eval 'if true; end'
end
$ ruby objectspace.rb
27
28
29
30
31
32
33
34
35
36
$
count_tdata_objects

require 'objspace'

p ObjectSpace.count_tdata_objects # =>
{RubyVM::InstructionSequence=>64,
false=>13, ... }
count_tdata_objects

require 'objspace'

p ObjectSpace.count_tdata_objects # =>
{RubyVM::InstructionSequence=>64,
false=>13, ... }
count_tdata_objects


require 'objspace'
require 'fiddle'

10.times do
  Fiddle::Closure.new(0, [1])
  p ObjectSpace.count_tdata_objects[Fiddle::Closure]
end
$ ruby objectspace.rb
1
2
3
4
5
6
7
8
9
10
$
Fiddle
libffi wrapper
fiddle + dl
Fiddle


• Function calls
• Closure allocation
DL


• dlopen() wrapper
• memory management
Calling Functions
• Open dynamic library
• Locate function pointer
• Wrap function pointer
• Call function
Wrapping "sin"
require 'fiddle'

libm = DL.dlopen('libm.dylib')

function = Fiddle::Function.new(
  libm['sin'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts function.call(90 * Math::PI / 180)
Wrapping "sin"
require 'fiddle'

libm = DL.dlopen('libm.dylib')

function = Fiddle::Function.new(
  libm['sin'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts function.call(90 * Math::PI / 180)
Wrapping "sin"
require 'fiddle'

libm = DL.dlopen('libm.dylib')

function = Fiddle::Function.new(
  libm['sin'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts function.call(90 * Math::PI / 180)
Wrapping "sin"
require 'fiddle'

libm = DL.dlopen('libm.dylib')

function = Fiddle::Function.new(
  libm['sin'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts function.call(90 * Math::PI / 180)
Wrapping "sin"
require 'fiddle'

libm = DL.dlopen('libm.dylib')

function = Fiddle::Function.new(
  libm['sin'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts function.call(90 * Math::PI / 180)
Creating Closures
double (func *)(double)
require 'fiddle'

class MySin < Fiddle::Closure
  def call number
    Math.sin(number)
  end
end

function = MySin.new(
  Fiddle::TYPE_DOUBLE,
  [Fiddle::TYPE_DOUBLE]
)

puts function.call(90 * Math::PI / 180)
require 'fiddle'

class MySin < Fiddle::Closure
  def call(number)
    Math.sin(number)
  end
end

function = MySin.new(
  Fiddle::TYPE_DOUBLE,
  [Fiddle::TYPE_DOUBLE]
)

puts function.call(90 * Math::PI / 180)
require 'fiddle'

class MySin < Fiddle::Closure
  def call(number)
    Math.sin(number)
  end
end

function = MySin.new(
  Fiddle::TYPE_DOUBLE,
  [Fiddle::TYPE_DOUBLE]
)

puts function.call(90 * Math::PI / 180)
require 'fiddle'

class MySin < Fiddle::Closure
  def call(number)
    Math.sin(number)
  end
end

function = MySin.new(
  Fiddle::TYPE_DOUBLE,
  [Fiddle::TYPE_DOUBLE]
)

puts function.call(90 * Math::PI / 180)
Using our Closure
class MySin < Fiddle::Closure
  def call number
    Math.sin(number)
  end
end

function = MySin.new(
  Fiddle::TYPE_DOUBLE,
  [Fiddle::TYPE_DOUBLE]
)

cfunc = Fiddle::Function.new(
  function,
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts cfunc.call(90 * Math::PI / 180)
class MySin < Fiddle::Closure
  def call number
    Math.sin(number)
  end
end

function = MySin.new(
  Fiddle::TYPE_DOUBLE,
  [Fiddle::TYPE_DOUBLE]
)

cfunc = Fiddle::Function.new(
  function,
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)

puts cfunc.call(90 * Math::PI / 180)
Fiddle Masquerade
ruby-ffi code
module Tidy
  extend FFI::Library

 ffi_lib "libtidy.dylib"

  attach_function   :tidyFileExists, [:string], :int
  attach_function   :tidyCreate, [], :pointer
  attach_function   :tidyParseString, [:pointer, :string], :int
  attach_function   :tidySaveStdout, [:pointer], :int
end

tdoc = Tidy.tidyCreate
Tidy.tidyParseString tdoc, "<title>Foo</title"
Tidy.tidySaveStdout tdoc
In terms of Fiddle
module FFI
  module Library
    TYPE_MAP = {
      :string => DL::TYPE_VOIDP,
      :pointer => DL::TYPE_VOIDP,
    }

   DL.constants.each do |const|
     next unless const.to_s =~ /^TYPE_/

     name = const.to_s.split('_', 2).last.downcase.to_sym
     TYPE_MAP[name] = DL.const_get(const)
   end

   def ffi_lib(lib)
     @lib = DL::Handle.new lib
   end

   def attach_function(name, args, ret)
     func = Fiddle::Function.new(
       @lib[name.to_s], args.map { |x| TYPE_MAP[x] }, TYPE_MAP[ret]
     )

      define_singleton_method(name) { |*args| func.call(*args) }
    end
  end
end
ruby-ffi code
module Tidy
  extend FFI::Library

 ffi_lib "libtidy.dylib"

  attach_function   :tidyFileExists, [:string], :int
  attach_function   :tidyCreate, [], :pointer
  attach_function   :tidyParseString, [:pointer, :string], :int
  attach_function   :tidySaveStdout, [:pointer], :int
end

tdoc = Tidy.tidyCreate
Tidy.tidyParseString tdoc, "<title>Foo</title"
Tidy.tidySaveStdout tdoc
Fiddle code
module Tidy
  extend FFI::Library

 ffi_lib "libtidy.dylib"

  attach_function   :tidyFileExists, [:string], :int
  attach_function   :tidyCreate, [], :pointer
  attach_function   :tidyParseString, [:pointer, :string], :int
  attach_function   :tidySaveStdout, [:pointer], :int
end

tdoc = Tidy.tidyCreate
Tidy.tidyParseString tdoc, "<title>Foo</title"
Tidy.tidySaveStdout tdoc
Psych
YAML Parser

• 1.9.2 and up
• Wraps libyaml
• Replaces Syck
• Opt-in
Opt-in Process
$ irb
irb(main):001:0>   require 'yaml'
=> true
irb(main):002:0>   YAML::ENGINE.syck?
=> true
irb(main):003:0>   YAML::ENGINE.yamler = 'psych'
=> "psych"
irb(main):004:0>   YAML::ENGINE.syck?
=> false
irb(main):005:0>
require 'psych'
Parsing & Dumping

require 'psych'

Psych.load('--- hello world!') # => 'hello world!'
Psych.dump('hello world!')     # => '--- hello world!'
'hello world!'.to_yaml         # => '--- hello world!'
JSON

Psych.load("['hello', 'world!']n")
  # => ["hello", "world!"]

Psych.to_json(%w{ hello world! })
  # => "['hello', 'world!']n"
JSON Disclaimer
Evented Parsing
Evented Parsing
class MyHandler < Psych::Handler
  def start_sequence(*args)
    puts "open ["
  end

  def end_sequence(*args)
    puts "close ]"
  end

  def scalar(value, anchor, tag, plain, quoted, style)
    puts value
  end
end
Evented Parsing


parser = Psych::Parser.new(MyHandler.new)
parser.parse(StringIO.new("['foo', 'bar']"))
Evented Parsing

$ ruby yml.rb
open [
foo
bar
close ]
$
Psych::Parser#parse(io_or_string)
Evented Emitting
(the hard way)
Psych::Emitter

emitter = Psych::Emitter.new($stdout)

emitter.start_stream(Psych::Parser::UTF8)
emitter.start_document([], [], false)
emitter.start_sequence(nil, nil, false, 1)
10.times {
  emitter.scalar('hello world', nil, nil, false, true, 1)
}
emitter.end_sequence
emitter.end_document true
emitter.end_stream
---
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
- 'hello   world'
Read
Psych::Handler
Streamed Emitting
(the easy way)
Psych::Stream

emitter = Psych::Stream.new($stdout)
emitter.start
emitter.push %w{ one two }
emitter.push %w{ three four }
emitter.finish
Psych::Stream

emitter = Psych::Stream.new($stdout)
emitter.start
emitter.push %w{ one two }
emitter.push %w{ three four }
emitter.finish
Psych::Stream
$ ruby yml.rb
---
- one
- two
...
---
- three
- four
...
Problem?
Streaming JSON
Psych::Stream


emitter = Psych::Stream.new($stdout)
emitter.start
emitter.push %w{ one two }
emitter.push %w{ three four }
emitter.finish
Psych::JSON::Stream


emitter = Psych::JSON::Stream.new($stdout)
emitter.start
emitter.push %w{ one two }
emitter.push %w{ three four }
emitter.finish
Psych::JSON::Stream


emitter = Psych::JSON::Stream.new($stdout)
emitter.start
emitter.push %w{ one two }
emitter.push %w{ three four }
emitter.finish
Psych::JSON::Stream


--- ['one', 'two']
...
--- ['three', 'four']
...
Uses?
More Info
THE END
Questions?
Coverage
Methods


• Coverage.start
• Coverage.result
a.rb
###
# It's my class!
class Foo
  def initialize
    @thought = 0
    10.times {
      @thought += 1 # thinking
    }
  end

  def rested?
    if @thought > 8
      false
    else
      true
    end
  end
end

Foo.new.rested?
a.rb
###
# It's my class!
class Foo
  def initialize
    @thought = 0
    10.times {
      @thought += 1 # thinking
    }
  end

  def rested?
    if @thought > 8
      false
    else
      true
    end
  end
end

Foo.new.rested?
a.rb
###
# It's my class!
class Foo
  def initialize
    @thought = 0
    10.times {
      @thought += 1 # thinking
    }
  end

  def rested?
    if @thought > 8
      false
    else
      true
    end
  end
end

Foo.new.rested?
a.rb
###
# It's my class!
class Foo
  def initialize
    @thought = 0
    10.times {
      @thought += 1 # thinking
    }
  end

  def rested?
    if @thought > 8
      false
    else
      true
    end
  end
end

Foo.new.rested?
require 'coverage'

Coverage.start
require 'a'
p Coverage.result
require 'coverage'

Coverage.start
require 'a'
p Coverage.result
Coverage.result


{"/Users/apatterson/git/code/a.rb"=>[nil,
nil, 1, 1, 1, 1, 10, nil, nil, nil, 1, 1, 1,
nil, 0, nil, nil, nil, nil, 1]}
We've Learned
We've Learned

• Lines executed
We've Learned

• Lines executed
• # times a line was executed
We've Learned

• Lines executed
• # times a line was executed
• Lines that can't be executed
We can deduce
We can deduce


• Coverage
We can deduce


• Coverage
• Hotspots (code heatmap)
SimpleCov
http://github.com/colszowka/simplecov
Read More Here!
   http://bit.ly/19coverage

Weitere ähnliche Inhalte

Was ist angesagt?

The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202Mahmoud Samir Fayed
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Workhorse Computing
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationAttila Balazs
 
Pytest: escreva menos, teste mais
Pytest: escreva menos, teste maisPytest: escreva menos, teste mais
Pytest: escreva menos, teste maisErick Wilder
 
Ruby closures, how are they possible?
Ruby closures, how are they possible?Ruby closures, how are they possible?
Ruby closures, how are they possible?Carlos Alonso Pérez
 
Py.test
Py.testPy.test
Py.testsoasme
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
Testes pythonicos com pytest
Testes pythonicos com pytestTestes pythonicos com pytest
Testes pythonicos com pytestviniciusban
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnitferca_sl
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
Publishing a Perl6 Module
Publishing a Perl6 ModulePublishing a Perl6 Module
Publishing a Perl6 Moduleast_j
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6garux
 
The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189Mahmoud Samir Fayed
 

Was ist angesagt? (20)

The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
 
Pytest: escreva menos, teste mais
Pytest: escreva menos, teste maisPytest: escreva menos, teste mais
Pytest: escreva menos, teste mais
 
Ruby closures, how are they possible?
Ruby closures, how are they possible?Ruby closures, how are they possible?
Ruby closures, how are they possible?
 
Py.test
Py.testPy.test
Py.test
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
Testes pythonicos com pytest
Testes pythonicos com pytestTestes pythonicos com pytest
Testes pythonicos com pytest
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Publishing a Perl6 Module
Publishing a Perl6 ModulePublishing a Perl6 Module
Publishing a Perl6 Module
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Python decorators
Python decoratorsPython decorators
Python decorators
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189The Ring programming language version 1.6 book - Part 185 of 189
The Ring programming language version 1.6 book - Part 185 of 189
 

Andere mochten auch

Birthplace of country music
Birthplace of country musicBirthplace of country music
Birthplace of country musicMdbrandon32
 
Fanatics media coverage clip book, fall 2012
Fanatics media coverage clip book, fall 2012Fanatics media coverage clip book, fall 2012
Fanatics media coverage clip book, fall 2012bongozap
 
áNgeles de berlín
áNgeles de berlín áNgeles de berlín
áNgeles de berlín circusromanus
 

Andere mochten auch (8)

Nordic Ruby 2011
Nordic Ruby 2011Nordic Ruby 2011
Nordic Ruby 2011
 
Birthplace of country music
Birthplace of country musicBirthplace of country music
Birthplace of country music
 
Fanatics media coverage clip book, fall 2012
Fanatics media coverage clip book, fall 2012Fanatics media coverage clip book, fall 2012
Fanatics media coverage clip book, fall 2012
 
áNgeles de berlín
áNgeles de berlín áNgeles de berlín
áNgeles de berlín
 
Notre Dame Afb Seminar 2009
Notre Dame Afb Seminar 2009Notre Dame Afb Seminar 2009
Notre Dame Afb Seminar 2009
 
RubyConf Argentina 2011
RubyConf Argentina 2011RubyConf Argentina 2011
RubyConf Argentina 2011
 
RubyConf Brazil 2010
RubyConf Brazil 2010RubyConf Brazil 2010
RubyConf Brazil 2010
 
Worst. Ideas. Ever.
Worst. Ideas. Ever.Worst. Ideas. Ever.
Worst. Ideas. Ever.
 

Ähnlich wie Hidden Gems of Ruby 1.9

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
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parserkamaelian
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of RubyTom Crinson
 
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...Rodolfo Carvalho
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)Wesley Beary
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011tobiascrawley
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachablePamela Fox
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the CloudWesley Beary
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 

Ähnlich wie Hidden Gems of Ruby 1.9 (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
 
Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Deixe o teste infectar você
Deixe o teste infectar vocêDeixe o teste infectar você
Deixe o teste infectar você
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
 
Ruby 2.0
Ruby 2.0Ruby 2.0
Ruby 2.0
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 

Hidden Gems of Ruby 1.9