MWRC 2010 - Notes from Day 1. 132
MWRC
Giles Bowkett - making some music with ruby Archaeopteryx
- Giles Bowkett: Archaeopteryx: A Ruby MIDI Generator
- learn probability matrix
- google is easy if you understand prob matrix
- google spell check in 21 lines of python
- wonder how easy OCR would seem in this context?
- don't understand python community.... why are there not more dick jokes about pythons?
- how is there not a web framework called trouser snake?
- oh yeah... better talk about lambdas
James Golick - Cooking with Chef - @jamesgolick github.com/jamesgolick
- Chef: Quick and Tasty Ruby Powered Server Configuration
- sysadmin work is boring
- too many config languages
- amazed if anyone can get nagios working on a consistent basis
- ues recipes to install packages
- recipes written in ruby
- create services -> status, restart, reload, etc.
- templates to create config files
- erb
- notifies restart if config changes
- autoreload on save very handy for things like dynamic lists of ips that change when you start a new EC2 instance
- makes setting up stuff like haproxy and heartbeat easier
- security
- easy to include iptables
- always turn off password ssh logins - easier to remember when part of your cookbook
- look into chef server and chef client
Joe Damato - RVM
- RVM: Ruby Version Manager - RVM Ruby Version Manager - Documentation
- RVM gemset - different gemsets for the same ruby version per project
- create rvmrc to switch env automatically when you cd into a project directory
- export gemsets?
- should you use gemsets or just bundler
Loren Segal - Documentation with YARD
- Yet Another Ruby Documentor
- Talk about documentation in general
- Documentation to help you think about your API
- What makes documentation good?
- consistency -> pick a style and stick with it
- correct -> it can be wrong and should be audited
- coherent
- YARD
- meta-data
- @param [Symbol] req_type :get or :post
- ....
- yard-respec
- shows rspec specs alongside method docs
- yard-sinatra
- shows your routes for api
Michael Jackson - Rack for web developers
- Rack: a Ruby Webserver Interface
- Read the Spec
- blah, blah, blah
- rack is cool in that it allows web frameworks to communicate with web servers, but not sure you care that much unless making a web framework
Yehuda Katz - Modularity - Lessons learned from Rails 3
- Try to become modular too soon and you will be wrong
- Become modular once lack of modularity is hurting you, then decouple
- Constants -> Globals
- router.url_for in rails 3
- easier to track down where instance variables came from than Globals
- eliminate things that are global
- tests are the canary in the coal mine
- instead of hard coding contants, pass things around
- be subspicious of Contant.foo
- stop caring about object allocations
- object allocations are essentially free
- Render
- Controller -> ViewPathSet -> ViewPath -> Template (on file system)
- Used to assume actual file path
- hard to cache
- Template.new takes a path
- Now
- Caller -> LookupContext -> ViewPaths -> PathResolver-> Resolver -> Template
- Template.new takes a source
- Could overide PathResolver to pull from database or S3 or something
- could be useful in making a CMS system with Rails
- Use Modules
- don't put methods you want people to be able to override in a class, make a module
- then you cna call super
- Use ActiveSupport::Concern
Paul Sadauskas - HTTP
- read the spec :-)
- prevent the requests that you don't have to answer
- Persistent Connections - so you don't have to create a new TCP connection for every request --- keepalive=onC
- Caching
- how do you decide when something is stale?
Jeff Casimir - Ruby Processing
- dynamically generate images in ruby app
- uses jruby
- first built to create verticle column headers
- Distributed Programming with Ruby -> to learn how to send jobs to ruby processing from rails
- Beanstalkd -> simple fast background processing -> brew install beanstalkd
MWRC 2010 - Day 1 Live Video
The conference is about to start in 30 minutes, the room starts to buzz. The confreaks guys have their camera and video recording equipment all setup. So you will be able to catch up the conference online soon. Somehow I really like single track conferences and the sessions seem really great and will be fast passed, 30 to 45 minutes. Check out the schedule. So I will sit back and enjoy the show.
Follow it live on Justin TV!!
Watch live video from Mountain West Ruby Conference on Justin.tvSalt Lake City is definitively a beautiful city, surrounded by it’s mountains…
RMagick (from source) on Snow Leopard 39
After the release of 10.5, I published an article about building RMagick from source on Leopard. I won’t rehash the why, you can read the original article for that. My clean install necessitated updating the RMagick script, so here’s what worked for me to install from source on Snow Leopard! For the impatient, here’s the download link: rmagick-build.sh
First, we start with installing wget, as it seems to be a bit more clever than curl about dealing with mirrors, etc. Then, we compile and install each prerequisite package. Finally, we install the gem.
All the links in the script worked for me, but, depending on your location, network, conditions, etc, your mileage may vary. Enjoy!
#!/bin/sh
# install wget, which is cleverer than curl
curl -O http://ftp.gnu.org/gnu/wget/wget-1.11.tar.gz
tar zxvf wget-1.11.tar.gz
cd wget-1.11
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src
# prerequisite packages
wget http://nongnu.askapache.com/freetype/freetype-2.3.9.tar.gz
tar zxvf freetype-2.3.9.tar.gz
cd freetype-2.3.9
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src
wget http://superb-west.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.39.tar.gz
tar zxvf libpng-1.2.39.tar.gz
cd libpng-1.2.39
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src
wget ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
tar xzvf jpegsrc.v6b.tar.gz
cd jpeg-6b
ln -s `which glibtool` ./libtool
export MACOSX_DEPLOYMENT_TARGET=10.6
./configure --enable-shared --prefix=/usr/local
make
sudo make install
cd /usr/local/src
wget ftp://ftp.remotesensing.org/libtiff/tiff-3.9.1.tar.gz
tar xzvf tiff-3.9.1.tar.gz
cd tiff-3.9.1
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src
wget http://superb-west.dl.sourceforge.net/sourceforge/wvware/libwmf-0.2.8.4.tar.gz
tar xzvf libwmf-0.2.8.4.tar.gz
cd libwmf-0.2.8.4
make clean
./configure
make
sudo make install
cd /usr/local/src
wget http://www.littlecms.com/lcms-1.17.tar.gz
tar xzvf lcms-1.17.tar.gz
cd lcms-1.17
make clean
./configure
make
sudo make install
cd /usr/local/src
wget ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs870/ghostscript-8.70.tar.gz
tar zxvf ghostscript-8.70.tar.gz
cd ghostscript-8.70
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src
wget ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs860/ghostscript-fonts-std-8.11.tar.gz
tar zxvf ghostscript-fonts-std-8.11.tar.gz
sudo mv fonts /usr/local/share/ghostscript
# Image Magick
wget ftp://ftp.fifi.org/pub/ImageMagick/ImageMagick.tar.gz
tar xzvf ImageMagick.tar.gz
cd `ls | grep ImageMagick-`
export CPPFLAGS=-I/usr/local/include
export LDFLAGS=-L/usr/local/lib
./configure --prefix=/usr/local --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8 --with-gs-font-dir=/usr/local/share/ghostscript/fonts --disable-openmp
make
sudo make install
cd /usr/local/src
# RMagick
sudo gem install rmagickUPDATE There is a bug with libgomp that breaks the convert utility (See comments below). the --disable-openmp configure option has been added to the script to fix this.
UPDATE 2 A new patchlevel of ImageMagick has been released that supersedes the original one referenced in this script, and the original has been removed from the server. Thanks to Sebastian for this update that will grab the latest release.
MWRC - Thanks you, that what awesome!
Check out some of the comments from the last few hours or check all tweets regarding #mwrc.
MWRC - Moutain West Ruby Conference is about to start.

The Confreaks guys did setup their cameras, sound and lights, so you will certainly be able to see all the talks in a few weeks.
The conference takes place in Salt Lake City, the scenery is impressive as the city is surrounded by high mountains…even for someone living in Denver. The picture above was taken just before the conference starts and shows the atrium we gonna spend the next two days in. The talks looks really cool and tonight the Engine Yard’s Hackfest 2.0 in suite next to mine at the Hilton Salt Lake City Center.
Advanced Ruby - Day 3 2

The first two days of the training were really excellent. Great pace, clear explanations and samples, very technical, Chad and Dave really rock at Ruby.
Making Domain-Specific Languages
We start with a discussion on DSL versus an API.
Meat-and-Potato DSLs
- Block based API.
- Directly manipulating domain model classes
- Defining classes and methods
- Manually typing repetitive, low-level code
Example is Rake. Rake is a dependency oriented programming language.
Eexample from Dhaka (a paraser generator)
for_pattern("\n") do
create_token("newline")
endmethod_missing Trick
require 'pp'
class CommandListener
def initialize
@commands = []
end
def method_missing(*args)
@commands << args
self
end
end
listener = CommandListener.new
listener.instance_eval do
this object accepts whatever you type and stores it
end
pp listeneroutputs:
#<CommandListener:0x80264 @commands= [[:you, CommandListener], [:whatever, #<CommandListener:0x80264 ...>], [:accepts, #<CommandListener:0x80264 ...>], [:object, #<CommandListener:0x80264 ...>], [:this, #<CommandListener:0x80264 ...>], [:it], [:stores, #<CommandListener:0x80264 ...>]]>
listener = CommandListener.new
listener.instance_eval do
this.object.accepts.whatever.commands.and.stores.it
end
pp listeneroutputs:
#<CommandListener:0x712b4 @commands= [[:this], [:object], [:accepts], [:whatever], [:commands], [:and], [:stores], [:it]]>
Note any keyword can be used with method_missing…E.g. freeze is not a missing method.
Now by using a BlankSlate object we can avoid this issue:
class BlankSlate
instance_methods.each do |method|
undef_method(method) unless method =~ /^__/ || method == 'instance_eval'
end
endWe can now create a command listener that can use any commands:
require 'pp'
class CommandListener < BlankSlate
def initialize
@commands = []
end
def method_missing(*args)
@commands << args unless [:inspect, :to_s].include? args.first
self
end
def pretty_print(pp)
pp.output.write @commands.inspect
end
end
listener = CommandListener.new
listener.instance_eval do
You can even type freeze!
end
pp listenerAnd we get the following output:
[[:freeze!], [:type, #<CommandListener:0x7ee28>], [:even, #<CommandListener:0x7ee28>], [:can, #<CommandListener:0x7ee28>], [:You, #<CommandListener:0x7ee28>]]
On the same principals we just create a morse encoder, and of course Dave had to show off and interface with the speech function of OSX and another version that interfaces with the MIDI controller.
Exotic Control Flow
Creating a loop with continuations
def start_loop
callcc{|c|c }
end
def end_loop(c)
c.call(c)
end
i = 0
again = start_loop
puts i
i += 1
end_loop(again) unless i > 5Moving on…
We voted on what to cover next as we won’t have time to cover every thing…and the winners are:
* Concurrency .................. * Debugging/Profiling ................ * JRuby ...... * Ruby Extras ........... * Distributed Programming ......................
Distributed Programming
DRb
Marshaling
>> h = {:x => 1} >> Marshal.dump(h) => ”\004\b{\006:\006xi\006” >> Marshal.load(_) => {:x=>1}
DRB Server
require 'drb/drb'
require 'ostruct'
DRb.start_service("druby://localhost:4321", OpenStruct.new)
DRb.thread.joinDRb Client
require ‘drb’DRB.start_service
o = DRbOject.new_with_url("druby:''localhost:4321")
o.last_accessed = Time.now
o.some_other_arbitrary_method = "Set this on the open struct"By default Pass-by-value, but can be Pass-by-reference can be enabled by including DRbUndumped.
- Rinda
- Ring
...
That’s all Folk! ...my hands/brain where running tired during the last hour :-)
That was an incredible 3 days thanks to Chad and Dave. So if you want to dive deeper in Ruby, the Advanced Ruby is the best way to get there!
Enjoy! Daniel
Starting an intense Ruby week.
Advanced Ruby - Day 2
1.class.ancestors
=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
1.class.instance_methods(false)
=> [:to_s, :-@, :+, :-, :*, :/, :div, :%, :modulo, :divmod, :fdiv, :**, :abs, :magnitude, :==, :<=>, :>, :>=, :<, :<=, :~, :&, :|, :^, :[], :<<, :>>, :to_f, :size, :zero?, :odd?, :even?, :succ]
m = 1.method(:inspect)
=> #<Method: Fixnum(Kernel)#inspect> ...make it fast.
Rails doesn't scale and Ruby is slow. This said Ruby is arguably the slowest of the scripting languages with a naive implementation. But for 99% of the work we do, it's fast enough...Now let's talk about that last 1%. Premature optimization is the root of all evil - Donald Knuth.Benchmarking
In 1.9require 'benchmark'
puts Benchmark.measure {(1..1000000).map{|num| ""+num.to_s}}
0.940000 0.050000 0.990000 ( 1.001714) puts Benchmark.measure {(1..1000000).map{|num| ""+num.to_s}}
1.800000 0.050000 1.850000 ( 1.850319) require 'benchmark'
Benchmark.bm do |b|
b.report("map") {(1..1000000).map{|num| ""+num.to_s}}
b.report("inject") {(1..1000000).inject(""){|accum, num| ""+num.to_s}}
end
user system total real
map 1.970000 0.070000 2.040000 ( 2.077786)
inject 1.910000 0.010000 1.920000 ( 1.978541) Don't Use Ruby
* C (or OCAML?) extensions * Sockets * DL * Don't use Ruby at all DL is "Pure Ruby" way of calling native code form shared libraries.require 'dl/import'
require 'dl/struct' memoization
def fib(n)
@k||={}
n<=2 ? 1 : (@k[n-1]||=fib(n-1))+(@k[n-2]||=fib(n-2))
end
puts fib(200)
280571172992510140037611932413038677189525
Program exited with code #0 after 0.02 seconds def fib(n)
if n <= 2
1
else
fib(n-1) + fib(n-2)
end
end
alias :pre_memoized_fib :fib
def fib(n)
@cache ||= {}
@cache[n] ||= pre_memoized_fib(n)
end The Ruby Object Model
Now we move onto the essence of an Object in Ruby. * self is the "current object" * self always as a value * two things change self: 1) method calls 2) class or module definitionclass << str # << opens up the singleton class. Arrows seem to go wrong way.
p self # ghost class: <Class:#<String:0x1d0ec>> - class of the class String
def speak
puts "miaow"
end
end
puts str.speak
class Dave
class << self # puts the methods into the singleton class and becomes class methods
def do_something
end
end
end
class Person < Struct.new(:name, :age)
def greet
puts "Hello #{self.name}"
end
end
f = Person.new("Chad", 28) module Logger
def log(msg)
puts msg
end
end
class Album
include Logger
end
Album.ancestors # => [Album, Logger, Object, Kernel]
# Note that Logger becomes ancestor of Album...It's insert a generated class named after the module that shares the method table. module Speak
def hello
puts "hello"
end
end
str = "cat"
str.extend Speak
puts str.hello Metaprogramming
After the break we will be diving into metaprogramming. I saw his talk at the Advanced Rails Studio a while back and took some notes then. I will therefore sit back, relax, and code along his examples.Library Organization
Advanced Ruby - Day 1
Let’s get started. I’m at the Advanced Ruby training. Here are the topics we gonna cover
- Blocks, Procs, and Closures
- Ruby 1.9
- Your Own, Private Ruby
- Design in a Dynamic Language
- Messin’ with Types
- ...make it fast.
- The Ruby Object Model
- Metaprogramming
- Making Domains-Specific Languages
- Concurrency
- Exotic Control Flow
- Library Organization
- Debugging and Profiling
- JRuby
- Ruby Extras
- Distributed Programming
- Onward and Upward!
In fact when I saw the topics that will be covered by Dave Thomas and Chad Fowler, and the fact that some of my collogues from Pinnacol where attending I had to join…Oh yea, it’s a 25 minute drive from home too.
So this morning I woke up and installed Ruby 1.9. I didn’t use multiruby as many do I just downloaded Ruby 1.9.1-p0 from http://www.ruby-lang.org/en/downloads. These are the steps to install:cd ruby-1.9.1-p0 autoconf ./configure --prefix=/usr/local/ruby1.9 make sudo make install
Then you can check the version by
$/usr/local/ruby1.9/bin/ruby -v
ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-darwin9.6.0]
$/usr/local/ruby1.9/bin/irb
RUBY_VERSION
=> "1.9.1"I didn’t add /usr/local/ruby1.9/bin to my path, so the default ruby is still my mack default, 1.8.6 of my mac (ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]).
Keep on reading to see some of the code we are walking through. This said it’s hard to convey how much value Chad and Dave are passing along with all their deep explanations of each of the examples…
Objectives
Deep The “Why” not just the “How” Explore Ruby’s Lesser-kown Corners Pragmatic, not Dogmatic Discussion for Highest Group Value
Blocks, Procs, and Closures
Blocks
one two {...} # binds to #two, and result of that is passed to one
one two do … end # block bind to #one, and two is passed to as argument.
Built-in support:
- block_given?
- loop
- yield
- break, redo, next, retry
def show_break
puts "before yield"
yield
puts "after yield" # never make it here
end
puts "before call"
result = show_break do
puts "before break"
break 123
puts "after break" # never make it here
end
puts "after call, result = #{result}"The output of the above code is
before call before yield before break after call, result = 123
Then Dave and Chad explain in details the next, redo, and retry keywords. Note retry is removed in 1.9.
Blocks Into Objects
def show_block_param(&block)
puts block.inspect # use the blokc
[1,2,3].each &block # pass the block along
puts block.call
yield
end
show_block_param { puts "in block"}Using lambda, proc, and Proc.new
- 1.8: proc and lambda are synonyms
- 1.9: proc and Proc.new are synonyms
So don’t use proc. Lambda closer to method calling Proc.new uses parallel assignment rules for parameter passing
Proc.new { |a,b| }.call(1,2,3) # OK
lambda { |a,b| }.call (1) # ArgumentError: wrong number of args (1 for 2)
Dave goes onto the parameters and yield, followed by Return form blocks.
def meth(&block)
block.call
end
b = Proc.new { return 99 }
puts meth(&b) # LocalJumpError: unexpected returnBindings
Encapsulate the context at a point of execution
class A
attr_writer :ivar
def initialize
@ivar = 123
end
def get_binding
ivar = "ivar"
binding
end
end
a = A.new
bind = a.get_binding { "block value" }
eval "puts ivar", bind # => ivar
eval "puts @ivar", bind # => 123
a.ivar = "new value"
eval "puts ivar", bind # => ivar
eval "puts @ivar", bind # => new valueClosures
Blocks carry with them the binding in which they were created
def block_in_sandbox(param)
ivar = "local variable"
lambda do
puts "param = #{param}"
puts "ivar = #{ivar}"
end
end
block = block_in_sandbox(99)
block.call
# param = 99
# ivar = local variableThen we moved onto an exercise to create a counter with what we just learned:
require 'test/unit'
def counter(start=0, increment=1)
start -= increment
lambda do
start += increment
end
end
class CounterTest < Test::Unit::TestCase
def test_counter
result = counter(0,2)
assert_equal 0, result.call
assert_equal 2, result.call
assert_equal 4, result.call
end
def test_another_one
another_one = counter(10, 3)
assert_equal 10, another_one.call
assert_equal 13, another_one.call
assert_equal 16, another_one.call
end
end
# 2 tests, 6 assertions, 0 failures, 0 errorsBlocks, closures, and define_method
class Example
def self.create_multiplier(name, factor)
define_method(name) do |arg|
arg * factor
end
end
end
Example.create_multiplier(:double, 2)
Example.create_multiplier(:triple, 3)
eg = Example.new
puts eg.double(33) # 66
puts eg.triple(33) # 99Ruby Internals
Now we are going lower level than we want to…Looking at the source of Ruby:
- Main interpreter in top-level source
- Ruby libraries in lib/
- C libraries in ext/
- Architecture-sepcific stuff in bcc32/, win32/, wince/ and 68k/
Most important files parse.y and eval.c
If you install ruby like I listed at the start of this entry you have all the source files, I have mine under /Users/daniel/Downloads/ruby-1.9.1-p0. Opening in textmate it looks as follows

ParseTree shows the nodes
sudo gem install ParseTree Successfully installed RubyInline-3.8.1 Successfully installed sexp_processor-3.0.1 Successfully installed ParseTree-3.0.3
require 'rubygems'
require 'parse_tree'
class Daniel
def talk
"salut"
end
end
p = ParseTree.new
p.parse_tree(Daniel).to_yaml
---
- - :class
- :Daniel
- - :const
- :Object
- - :defn
- :talk
- - :scope
- - :block
- - :args
- - :str
- salut
=> nil- Note, doesn’t work i 1.9
- In 1.9 can call the interpreter
- Also ripper library, gives the output of the parse.
parse.y
Chad now explain how the parser works. In the parser.y you’ll find exactly how the parsing works. It’s over 10000 lines for Ruby 1.9
if_tail : opt_else
| keyword_elsif expr_value then
compstmt
if_tail
{
/*%%%*/
$$ = NEW_IF(cond($2), $4, $5);
fixpos($$, $2);
/*%
$$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
%*/
}
;
expr_value : expr
{
/*%%%*/
value_expr($1);
$$ = $1;
if (!$$) $$ = NEW_NIL();
/*%
$$ = $1;
%*/
}
;Naming Conventions
- NODE_XX type of a node
- rb_cXxxx class object for Ruby clas Xxx
- rb_mXxxx module object for Ruby module xxxx
- rb_xxx C-implementation of a Ruby method
- Qxxx immediate value of Qnil
- RXXXXXX
Object Representation
Look in ruby.h for definition
To find Classes and Modules you can search in the c files:
$ grep String *.c | grep rb_define_class
string.c: rb_cString = rb_define_class("String", rb_cObject);If we look in string.c we see how the methods of the String Ruby class are defined in c.
void
Init_String(void)
{
#undef rb_intern
#define rb_intern(str) rb_intern_const(str)
rb_cString = rb_define_class("String", rb_cObject);
rb_include_module(rb_cString, rb_mComparable);
rb_define_alloc_func(rb_cString, str_alloc);
rb_define_singleton_method(rb_cString, "try_convert", rb_str_s_try_convert, 1);
rb_define_method(rb_cString, "initialize", rb_str_init, -1);
rb_define_method(rb_cString, "initialize_copy", rb_str_replace, 1);
rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1);
rb_define_method(rb_cString, "==", rb_str_equal, 1);
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
...Writing Extensions
Why?
- Interface to external libraries
- Performance
- Accessing internal
- Showing off
C-api is really nice.
Recipe is: create new directory, create source .c file. Create extconf.rb script and run it (requires ‘mkmf’). make. make install…It just all works.
Practice in your own user-local Ruby copy.
Example wrapping the Tidy library.
And onto lunch and exercise…Back at 1:15pm
- How many build-in classes define a to_i method?
- What’s the difference between Symbol#to_i and Symbol#to_int?
Ruby 1.9
- Encoding support and multinationalization
- Method Calling
- Blocks, Procs, and Iterators
- Regular Expressions
- Fibers
- Lots more…
- Performance
The 1.9 rdoc can be found here
# default argument values not only at end of argument list.
def lunch(spam=false, how_much)
spam ? puts("no thanks") : puts(how_much)
end
lunch(2)
lunch(true, 2)
#symbol to proc backed in
puts ['daffy', 'donald'].map(&:upcase)
# enumerator
e = [1,2,3].each
p e.next
p e.next
e.rewind
p e.next
# Enumerator halts loops
letters = ('a'..'e').to_enum
loop do
puts "STARTING: #{letters.next}" # .next Stops the loop at the end by raising StopIteration. Can call it your self.
end
puts "DONE"
# Stabby Procs
l = lambda{|x,y| "woo ugly #{x+y}"}.call(1,2) # 1.8
puts l
l =->x,y{"woo ugly #{x+y}"}.(1,2) # 1.9
puts l
# === is Margic
less_than_one_thousand =-> v{v<1000}
divisible_by_three =->v{v % 3 ==0}
case 909
when less_than_one_thousand
puts "#is Less than a thousand"
when divisible_by_three
puts "is Divisible by three"
end
puts 1005 === less_than_one_thousand
# Block paramters always local to block
n = 123
10.times do |n|
end
puts n
# Can declare block-local varaibles
number_processded = 12
pizza_shop =->(orders; number_processded) do # ; means use outside scope
puts "inside:#{number_processded}"
end
pizza_shop[["pepperoni", "anchovies"]]
puts "number_processded:#{number_processded}"
# Curry
adder =->(x,y){x+y}.curry
add_three = adder.(3)
# add_three.(1,2) ArgumentError: wrong number of arguments (3 for 2)
add_four = adder[4]
# Reglar Expression - (?<name>pattern)
if /(?<key>\w+)=(?<value>.*)/ =~ "ruby=cool and fun"
puts key
puts value
end
# Reglar Expression
# see http://pragdave.blogs.pragprog.com/pragdave/2008/10/fun-with-ruby-19-regular-expressions.html
# Fibers
fibs = Fiber.new do
n1 = n2 = 1
loop do
Fiber.yield n1
n1, n2 = n2, n1+n2
puts "n1:#{n1} n2:#{n2}"
end
end
10.times { print fibs.resume}
# Fibers - continuation
require 'continuation' # basis of continuation
require 'fiber' # symetrical coroutines
More Ruby 1.9 goodness
- RubyGems now backed in
- BasicObject
- Ripper: access to the parser
- Object#tap and Object#p
- Enumerable#cycle
- Hashes now retina their order
- Hash#select
- Minitest and minispec
# from http://pragdave.blogs.pragprog.com/pragdave/2008/04/babydoc.html
require 'ripper/filter'
require 'ripper'
# This class handles parser events, extracting
# comments and attaching them to class definitions
class BabyRDoc < Ripper::Filter
def initialize(*)
super
reset_state
end
def on_default(event, token, output)
reset_state
output
end
def on_sp(token, output) output end
alias on_nil on_sp
def on_comment(comment, output)
@comment << comment.sub(/^\s*#\s*/, " ")
output
end
def on_kw(name, output)
@expecting_class_name = (name == 'class')
output
end
def on_const(name, output)
if @expecting_class_name
output << "#{name}:\n"
output << @comment
end
reset_state
output
end
private
def reset_state
@comment = ""
@expecting_class_name = false
end
end
BabyRDoc.new(File.read(__FILE__)).parse(STDOUT)Performance
It’s really faster. Chad is showing some benchmarks, but experiencing makes you believe.
How to use 1.9 without blowing up your production version?
- Download or checkout source
- autoconf (if checked out)
- ./configure
- make
- make test
- sudo make install
Install’s it in /usr/local/ruby.
Now you may want to prefer installing it in it’s own directory. Then do
- ./configure—prefix=/usr/local/ruby19
- export PATH=/usr/local/ruby1.9/bin/:$PATH
When you install gems it install them in the ruby version you use to run the gem install.
require 'rbconfig'
puts RbConfig::CONFIGBut wait…you can make it better. Dave installs it in it’s home folder.
- ./configure—prefix=/Users/dave/ruby19
Design in a Dynamic Language
- Can write in Java style, but it’s better to write using ruby.
- Inheritance (is-a) .vs. Composition (has-a)
- Inheritance is the work of the devil
- Inheritance the exception, composition the norm
Composition
require 'forwardable'
class Queue
extend Forwardable
def initialize
@q = [ ] # prepare delegate object
end
# setup prefered interface, enq() and deq()...
def_delegator :@q, :push, :enq
def_delegator :@q, :shift, :deq
# support some general Array methods that fit Queues well
def_delegators :@q, :clear, :first, :push, :shift, :size
endRubyConf 2008 videos available at confreaks.com - Thank you!
I couldn’t make it this year to RubyConf so I am really thankful to see that most of the presentations are online at confreaks. It’s just awesome that these videos are made available online and so quickly after the conference and for free. It’s a real tribute to the Ruby community and it’s open and sharing spirit. Thanks guys! My understanding is that the rubyconf pays Confreaks to take, processes and distribute these videos. Let me know if the arrangement is different, to give credit where credit is due. Thanks RubyConf and the presenters, and good job Confreaks.
Here are the videos I selected for my commute this week.
- Keynote – Dave Thomas
- Questions & Answers – Yukihiro ‘Matz’ Matsumoto
- Introducing Red Sun – Ruby to Flash – Jonathan Branam
- MacRuby: Ruby for your Mac – Laurent Sansonetti
- OS X Application Development with HotCocoa – Rich Kilmer
- Hacking with ruby2ruby – Marc Chung
- Using Git in Ruby Applications – Scott Chacon
- Adrenaline-Driven Development – Bruce Williams
- Fear of Programming – Nahaniel Talbott
- Recovering from Enterprise – Jamis Buck
View the full list of videos available here.
You may wonder why I would watch videos during my commute. Effectively I drive 40 minutes each way to my customers (happen to be both near enough for me to drive and not tele-commute) and this gives me a chance to catch up on many of the excellent screencast and podcast out there. Now when one screencast really sticks out, I watch it again at night…without driving ;-).
This said I converted the confreaks small videos format (640×240) to the iPhone format using Quicktime pro, but I only get the sound…which is fine for my commute. Any hint on how I can convert them to also get the video going would be appreciated?
Enjoy! Daniel


