the joy of ruby
TRANSCRIPT
The Joy of Ruby
Clinton R. Nixon, Viget Labs
Ruby is designed to make programmers
happy. – Yukihiro Matsumoto
Simplicity
Openness
a = "hello world"
class String def no_vowels self.gsub(/[aeiou]/, '') endend
p a.no_vowels # "hll wrld"
Natural Language
case yearwhen 1800...1900 then "19th century"when 1900...2000 then "20th century"else "21st century"end
"word".include? "a"
5.times do paint.stir!end
color "orange blossom" do red 224 yellow 147 blue 22end
An IntroducDon to Ruby
The Ruby Language
Object-oriented
Functional Dynamic
Reflective
Imperative
Basic TypesInteger (Fixnum, Bignum)
Float
String
Symbol
Array
Hash
Boolean
8192
3.14159
"3.14159"
:corndog
["gala", "fuji"]
{:plums => 2, :pears => 7}
false
Object-‐Oriented
1.8.class # Float
Array.new(["a", "b", "c"]) # ["a", "b", "c"]
true.is_a?(Object) # truetrue.class # TrueClasstrue.methods # ["==", "===", "instance_eval", "freeze", "to_a",
Modules, Classes, and Objectsmodule Authentication def valid_api_keys Database.retrieve_all_keys end def authenticated?(api_key) valid_api_keys.include? api_key endend
class PublicAPI include Authentication def initialize(api_key) @api_key = api_key end def act if authenticated?(@api_key) do_a_thing end endend
Inheritanceclass PrivateAPI include Authentication def initialize(id, api_key) @client = DB.get_client(id) @api_key = api_key end def valid_api_keys @client.api_keys end def act if authenticated?(@api_key) @client.do_a_thing end end
end
class PublicAPI include Authentication def act if authenticated?(@api_key) do_a_thing end endend
class NewAPI < PublicAPI def act if authenticated?(@api_key) do_a_new_thing end endend
The Inheritance Chain
Self Class Modules
superclass
Dynamic & Duck Typing
It’s not what type of object you have
It’s what that object can do
Duck Typing in AcDon
class Rectangle < Struct.new(:width, :height) include Comparable def <=>(other) (self.width * self.height) <=> (other.width * other.height) end end
r1 = Rectangle.new(4, 10)r2 = Rectangle.new(5, 7)
r1 > r2 # => false
FuncDonal
Ruby has broad support for functional programming
But it’s not a functional language
You could say it’s pragmatically functional
Blocksnumbers = (1..10)numbers.map { |n| n * n }# => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]numbers.reduce { |total, n| total += n }# => 55
odd_test = proc { |n| n % 2 == 1 }numbers.select(&odd_test)# => [1, 3, 5, 7, 9]
def before_save(&block) @before_callbacks << blockend
First-‐class FuncDonsdef counter(x = 0) proc { x += 1 }end
next_num = counternext_num.call # => 1next_num.call # => 2next_num.call # => 3next_num.call # => 4
another_seq = counter(10)another_seq.call # => 11
First-‐class FuncDonsdef is_prime?(x) is_prime = proc do |n, m| if m > (n / 2) true elsif n % m == 0 false else is_prime.call(n, m + 1) end end is_prime.call(x, 2) if x >= 2end (1..23).select { |n| is_prime?(n) }# => [2, 3, 5, 7, 11, 13, 17, 19, 23]
ReflecDon
Struct.new(:AC, :THAC0).new.local_methods# => ["AC", "AC=", "THAC0", "THAC0=", # "[]", "[]=", "all?", "any?", ...]
a = Rational(1, 2)
a.instance_variables# => ["@denominator", "@numerator"]
a.instance_variable_get("@numerator")# => 1
Metaprogramming
module Accessors def access(var) define_method(var) do instance_variable_get("@#{var}") end define_method("#{var}=") do |val| instance_variable_set("@#{var}", val) end endend
Metaprogramming
class Monster extend Accessors access :damage def initialize(damage) @damage = damage endend
wampa = Monster.new("2d6")wampa.damage # => "2d6"wampa.damage = "1d12"
The Ruby Ecosystem
Rails, Rack, and Passenger
Other Web Frameworks
Merb
Sinatra
Ramaze
Waves
others
Web deployment
set :application, 'listy'set :repository, "[email protected]:viget/listyapp.git"set :scm, 'git'
role :web, "listyapp.com"role :app, "listyapp.com"role :db, "listyapp.com", :primary => true
set :user, "listy"set :deploy_to, "/home/listy/rails"
RubyGems
Standard package management tool
More like apt than CPAN
Included with Ruby 1.9
Open Source
The Ruby License is much like the MIT License.
Most Ruby gems are under the Ruby license or MIT License.
GitHub is the hub of most Ruby OS activity.
Other ImplementaDons
JRubyIronRubyMacRubyand others
Ruby Shared Values
TesDng
Rails was the first framework I used that came with testing built in.
Community has exploded in the last few years with testing tools.
It’s rare I see a project without tests.
ConvenDon over ConfiguraDon
“The three chief virtues of a programmer are: Laziness, Impatience and Hubris.” – Larry Wall, who is not a Ruby programmer
Version Control
Everyone should use version control, so this isn’t really a value.
But Ruby programmers are fanatics for their VCS.
Git is the VCS of choice.
Being distributed, it allows for easy public forks of projects, which has helped OS in Ruby.
Sharing
Ruby programmers have been chastised as self-promoters. I don’t see that as a bad thing.
We share everything: open source code, discoveries, tips and tricks.
Talk, talk, talk
Blog, blog, blog
Passion
I don’t know any Ruby programmers who aren’t excited about programming.
Why Ruby Was Right For Us(and Might Be Right For You)
O"en people, especially computer engineers, focus on the machines. They think, "By doing this, the machine will run faster. By doing this, the machine will run more effec>vely. ..." They are focusing on machines. But in fact we need to focus on humans, on how humans care about doing programming or opera>ng the applica>on of the machines.
– Matz
TranslaDon: Ruby is not so fast.
ProducDvityConventions and dynamism speed development.
There are ridiculous quotes about “3-10x.”
Personal observation: as a project goes on, it doesn’t get any harder, unlike other languages.
Will testing slow you down?
Morale
Anecdotally: people like to program in Ruby.
Productive people are happier.
Seeing instant results is very rewarding.
Broad UDlityText processing
Cross-platform GUI development: Monkeybars, Limelight, and Shoes
Server configuration management: Chef, Puppet, and Sprinkle
Web servers: Mongrel, Unicorn, and Thin
Testing other languages
and anything else that isn’t matheletic
PlaYorm AgnosDc
MRI runs on Windows, OS X, Linux, and most other Unixes.
JRuby runs anywhere Java will run.
IronRuby is going to make .NET awesome.
Passenger works with Apache.
But you can proxy through or use FastCGI from any web server, even IIS.
QuesDons