You are on page 1of 42

The Ruby Idiom

Ben Hughes
@rubiety
http://benhugh.es

Friday, April 22, 2011
Friday, April 22, 2011
“Ruby is
designed to make
programmers happy”
- Matz

Friday, April 22, 2011
Aesthetic Elegance
Very Idiomatic
Loose Syntax
Extremely Dynamic
Expressive

Friday, April 22, 2011
Blocks

Friday, April 22, 2011
people.each do |person|
puts person.name
end

1.upto(10) do |i|
puts "Counting #{i}"
end

5.times { puts "Hello" }

Friday, April 22, 2011
open "people.txt" do |file|
file.each_line do |line|
puts line.split(",").first
end
end

Friday, April 22, 2011
users.select {|u| u.age >= 21}.map(&:name).sort

Friday, April 22, 2011
class Person
end

Person.class # => Class

nil.class # => NilClass
true.class # => TrueClass

Friday, April 22, 2011
Open Classes

Friday, April 22, 2011
class String
def blank?
self == ""
end
end

Friday, April 22, 2011
class Numeric
def seconds
self
end

def minutes
self * 60
end 12.hours.from_now

def hours
self * 3600 2.minutes + 30.seconds
end

def from_now
Time.now + self
end
end
Friday, April 22, 2011
# Yes, Be Evil:
class Numeric
def +(another)
self - another
end
end

4 + 2 # => 2
Friday, April 22, 2011
Executable Declarations

zsh$
Friday, April 22, 2011
class Person
def name
@name
end

if Superpowers.enabled?
def give_superpowers
@ability = "Fly"
end
end
end
Friday, April 22, 2011
class Model
def self.acts_as_tree
define_method :parent do
find(parent_id)
end

define_method :children do
where(:parent_id => self.id)
end
end
end

class Category < Model
acts_as_tree @category.parent
end @category.children

Friday, April 22, 2011
Module Mix-ins

Friday, April 22, 2011
module Jazz
class Chord
end

class Scale
end
end

Jazz::Chord.new
Jazz::Scale.new
Friday, April 22, 2011
module FilePersistence
def load_from(path)
end
end

class MusicCollection
include Enumerable
include FilePersistence
end

@collection = FileCollection.new
@collection.load_from "songs"
@collection.each do |song|
song.play
end
Friday, April 22, 2011
Isn’t too much freedom a
bad thing?

Friday, April 22, 2011
In Theory? Yes.

In Practice?
It’s not as bad as you
would think...

Friday, April 22, 2011
Greater Good vs. Greater Evil

Solution
Space (Good)

Evil

Friday, April 22, 2011
Greater Good vs. Greater Evil

Solution Space (Good)

Pitfalls
(Evil)

Friday, April 22, 2011
Overlapping Safety

Safety/
Confidence
from Static
Typing

Friday, April 22, 2011
Overlapping Safety

SafetySafety/Confidence
from from
Static Typing Test Suite

Friday, April 22, 2011
Domain-Specific Languages

• Sub-Languages of Ruby for particular purposes
• High-Level Abstractions
• Captures Knowledge in an Extremely Readable Way

Friday, April 22, 2011
Markaby::Builder.new.html do
head { title "Boats.com" }
body do
h1 "Boats.com has great deals"
ul.specials do
li "$49 for a canoe"
li "$39 for a raft"
li "$29 for a huge boat"
end
end
end

Friday, April 22, 2011
<html>
<head><title>Boats.com</title></head>
<body>
<h1>Boats.com has great deals</h1>
<ul class="specials">
<li>$49 for a canoe</li>
<li>$39 for a raft</li>
<li>$29 for a huge boat</li>
</ul>
</body>
</html>

Friday, April 22, 2011
class Payment
state_machine :state, :initial => :new do
event :authorize do
transition :new => :authorized
end

event :capture do
transition :authorized => :captured
end

before_transition any => :authorize, :do => :authorize_card
before_transition any => :capture, :do => :capture_card
end
end

@payment = Payment.new
@payment.state # => "new"
@payment.authorize!
@payment.capture!

@payment.captured? # => true
Friday, April 22, 2011
class Article < ActiveRecord::Base
has_many :comments

scope :published, where(published: true)

validates :title, :presence => true
validates :content, :length => { minimum: 50 }
end

class Comment < ActiveRecord::Base
belongs_to :article

validates :name, :email, :comment, :presence => true

def approve!
update_attribute :approved, true
end
end

Friday, April 22, 2011
class User < ActiveRecord::Base
has_attached_file :avatar, styles: {
medium: "300x300>",
thumb: "100x100>"
}
end

<% form_for(@user) do |f| %>
<%= f.file_field :avatar %>
<% end %>

@user.avatar.url(:medium)

Friday, April 22, 2011
Chord['Ebmaj7'].notes
Chord['maj7'].in_key_of('Eb').notes
# => ['Eb', 'G', 'Bb', 'D']

Scale['Whole Tone'].notes
# => ['C', 'D', 'E', 'F#', 'G#', 'Bb']

Scale['Major'].in_key_of('Eb').modes['Dorian'].notes
# => ['F', 'G', 'Ab', 'Bb', 'C', 'D', 'Eb']

Scale['Major']['Dorian'].chords.symbols
# => ['min7', 'min6']

Chord['Amin7'].modes.names
# => ['A Dorian']

Friday, April 22, 2011
every 3.hours do
command "/usr/bin/my_great_command"
end

every 1.day, :at => ['4:30 am', '10:30 am'] do
runner "MyModel.task_to_run"
end

every :hour do
runner "SomeModel.ladeeda"
end

every :sunday, :at => '12pm' do
runner "Task.do_something_great"
end

Friday, April 22, 2011
Person.joins { articles.comments }.where {{
articles.comments => (
id.in([1,2,3]) | body.matches('First post!%')
)
}}.to_sql

=> SELECT "people".* FROM "people"
INNER JOIN "articles" ON "articles"."person_id" = "people"."id"
INNER JOIN "comments" ON
"comments"."article_id" = "articles"."id"
WHERE (("comments"."id" IN (1, 2, 3)
OR "comments"."body" LIKE 'First post!%'))

Friday, April 22, 2011
C mmunity

Friday, April 22, 2011
Cohesive & Active
Common Style/Idiom
Focuses on Quality
Passionate About Tools
Testing Your Software

Friday, April 22, 2011
Test Your
Damn Software

Friday, April 22, 2011
describe User do
before do
@user = User.create(:login => "joe", :password => "pw")
end

it "should be invalid without username" do
@user.username = ""
@user.should_not be_valid
@user.should have(1).error_on(:username)
end

it "should destroy" do
expect { @user.destroy }.to change { User.count }.by(-1)
end
end

Friday, April 22, 2011
describe Key do
it "should default to C" do
Key.default.name.should == "C"
end

it "should expose 12 primary keys" do
Key.should have(12).primaries
end

it "should treat Eb and D# as enharmonic" do
Key['Eb'].should be_enharmonic_with(Key['D#'])
end
end

Friday, April 22, 2011
It’s a great time to learn Ruby
• Rails 3 recently released - very solid!
• Ruby 1.9 - Runs on a proper VM and very fast
• Bundler / RVM for Ruby and Gem dependencies
• Other Rubies maturing:
JRuby, MacRuby, Rubinius
• Deployment easy with mod_rails or Heroku
• Strong community with resources/help
Friday, April 22, 2011
“Ruby fits my brain
like a glove”
- David Heinemeier Hansson

“Power with clarity
and choice”
- Glenn Vanderburg
Friday, April 22, 2011
Resources
• http://tryruby.org
• http://rubykoans.com
• http://sdruby.org

Ben Hughes
@rubiety
http://benhugh.es
Friday, April 22, 2011