A Few Facets
An Exploratory Introduction to Ruby
by Bruce Williams
Wednesday, March 11, 2009 1
My Background
Developer, Designer, Language Geek
ist since 2001
Also: Erlang, Io, Haskell, OCaml, ObjC,
More next week...
Python, Perl, Java, Lisp, Scheme, C/C++...
Wednesday, March 11, 2009 2
Thank You.
Wednesday, March 11, 2009 3
I believe people want to express themselves when
they program. [...] I tried to make people enjoy
programming and concentrate on the fun and
creative part of programming when they use Ruby.
松本行弘
MASUMOTO Yukihiro, “matz”
Wednesday, March 11, 2009 4
Ruby is a dynamic, reflective,
general purpose object-oriented
programming language.
[Link]
Wednesday, March 11, 2009 5
Wednesday, March 11, 2009 5
Ruby is a lightweight, dynamic,
reflective, general purpose
object-oriented programming
language.
Wednesday, March 11, 2009 5
Wednesday, March 11, 2009 5
Ruby is a lightweight, dynamic,
reflective, general purpose
object-oriented (and slightly
functional) programming
language.
Wednesday, March 11, 2009 5
Wednesday, March 11, 2009 5
Ruby is a lightweight, dynamic,
reflective, general purpose
object-oriented (and slightly
functional) programming
language with elegant, flexible
syntax.
Wednesday, March 11, 2009 5
Basic Literals
"Scotland on Rails".split(' ') [Link] do
puts "Simple is Beautiful!"
%("Go back," he said irritably.).size end
do_something_with(:this_symbol) [Link]?(12, 13)
String, Symbol Fixnum, Float
['this', :is, 1, "Array"]
{:hashes => 1, 'are' => 'unordered'}
%w(and so is this right here)
[Link]('and', :can_be, 'created', 'several ways')
# {'and' => :can_be, 'created' => 'several ways'}
and_this = []
or_this = [Link]
Array Hash
Wednesday, March 11, 2009 6
Variable Assignment & Scope
(main)
$global_variables
(class/module)
Constants or CONSTANTS, ::
(instance)
@@class_variables
@instance_variables
(method)
normal_variables
age = 13 age += 1
Assignment Reassignment
Wednesday, March 11, 2009 7
Control Structures
if car.needs_gas? unless car.needs_gas?
car.fill_up! [Link] 40
else
else
# 'else' clause not recommended
[Link] 40
car.fill_up!
end
end
car.fill_up! if car.needs_gas?
[Link] 40 unless car.needs_gas?
If Unless
case [Link]
while car.can_drive? 40
when 'Ford'
[Link] 40
# ...
end
when 'Porsche'
# ...
loop do
else
# Something else # do something forever
end end
Case Loops
Wednesday, March 11, 2009 8
Blocks
%w(one two three).each do |item|
[Link]('[Link]', 'w') do |f|
puts item
[Link] 'This is some output'
end
end
Iteration Transactions
<% admin do %>
[Link] :click do |event|
<p>Admin-only content</p>
[Link]!
<% end %>
end
<p>Normal Content<p>
Handlers Conditional Yield
Wednesday, March 11, 2009 9
Methods
def say_hello def say(text)
puts "Hello!" puts text
end end
say_hello say "Okay!"
# Hello! # Okay
Simple With Arguments
def remove_files(*files) def do_it(&block)
# `files' is an Array [Link] # same as `yield'
[Link] do |file| end
[Link] file
end do_it do
end puts "Hi"
remove_files '[Link]', '[Link]' end
“Splat” Args Assigning a Block
Wednesday, March 11, 2009 10
Classes
class Car
attr_reader :make, :model, :year class Coupe < Car
def initialize(make, model, year) def initialize(*args)
@make, @model, @year = make, model, year
super
end
def drive(distance)
@doors = 2
puts "Drove a #{@year} #{@make} #{@model} #{distance}" end
end end
end
Defining a Class Inheritance/Polymorphism
vroom = [Link] "Audi", "A4", 2008
[Link] '20km'
# Drove a 2008 Audi A4 20km
Instantiation
Wednesday, March 11, 2009 11
Enumerable
files = ['[Link]', '[Link]']
[Link] do |file| [Link] do |file|
[Link] file, '/destination/dir' [file, [Link](file).size]
end end
# [["[Link]", 71680], ["[Link]", 68009]]
each map/collect
[Link] { |f| [Link](f) > 70_000 } [Link]({}) do |manifest, filename|
# ['[Link]'] manifest[filename] = [Link](filename).size
[Link] { |f| [Link](f) > 70_000 } manifest
# '[Link]' end
[Link] { |f| [Link](f) > 70_000 } # {"[Link]" => 71680, "[Link]" => 68009}
# ['[Link]']
select, reject, detect inject
Wednesday, March 11, 2009 12
Mixins
class Car
module Conversions include Conversions
KM_PER_MILE = 1.609 def drive(distance, unit=:km)
distance = if unit == :km
def mi_to_km(miles) distance
miles * KM_PER_MILE
else
end
mi_to_km(distance)
def km_to_mi(kilometers) end
kilometers / KM_PER_MILE # Do something
end end
end # ...
end
Module Definition Include
Wednesday, March 11, 2009 13
Dynamic Features
"name".methods
# ["%", "select", "[]=", "inspect", "<<", "each_byte",
"method", "clone", "gsub", "casecmp", "public_methods",
"to_str", "partition", "tr_s", "empty?", ... [Link] do |n|
n =~ /[a-z]$/
[Link] do |meth|
obj.instance_eval <<-CODE
alias :original_#{meth} :#{meth}
def #{meth}(*args, &block)
puts "Doing #{meth}..."
Listing Methods result = original_#{meth}(*args, &block)
puts "Done doing #{meth}, result: \#{result}"
result
end
name = 'John' CODE
obj.instance_eval <<CODE end
def yell
puts "My name is #{name}!!!"
end
CODE
[Link]
# My name is John!!!
Dynamic Evaluation
Wednesday, March 11, 2009 14
Questions?
Slides will be available from [Link] and/or the conference website.
Wednesday, March 11, 2009 15