what i love about ruby
TRANSCRIPT
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Who I Am
Keith Bennett, keithrbennett at gmail.com
Software Developer living near Washington, DC, USA
Original hometown is New York City
25+ years experience, focusing on Ruby and Java, currently studying Android development
Technical Interests: Ruby, Android, Clojure
Other Interests: Travel, Music, Study of Massage and Asian and European Languages
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Obligatory Joke, Part 1
A DBA walks into a bar, steps in front of two tables and says...
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Obligatory Joke, Part 2
...may I join you?
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Please...
...ask me to slow down if I speak too quickly.
...ask me again if I forget.
...ask questions if anything I say is not clear.
...feel free to share your own observations and experiences.
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
What I Love About Ruby:Overview
Conciseness and Clarity, Not Ceremony (high signal to noise ratio)
Expressive Syntax
Powerful Enumerable Processing
Code Blocks and Closures
Everything’s an Object, even 1 and nil
Ranges
Regular Expressions
JRuby
IRB
OS Scripting Support
Metaprogramming
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Conciseness and Clarity, Not Ceremony:Main Program
Java:public class HelloWorld {
public static void main(String args) {
System.out.println("Hello world!");
}
}
Ruby:puts “Hello world!”
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Conciseness and Clarity, Not Ceremony:Instance Variable Access
Java:private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Ruby:attr_accessor :name
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Conciseness and Clarity, Not Ceremony:List/Array Subtraction
Java:public static List subtractList(List minuendList, List subtrahendList) { List differenceList = new ArrayList(); for (Object o : minuendList) { if (! subtrahendList.contains(o)) { differenceList.add(o); } } return differenceList;}
RubyminuendList – subtrahendList
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Conciseness and Clarity, Not Ceremony:List Manipulation
Java:public static List<Integer> calcDoubles(List<Integer> inputList) { List<Integer> outputList = new ArrayList<Integer>(); for (Integer n : inputList) { outputList.add(2 * n); } return outputList; }
Ruby:def calc_doubles(input_list) input_list.map { |n| 2 * n }end
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Conciseness and Clarity, Not Ceremony:Multiline Strings
"""
Dear #{customer_name},
Thank you for your purchase on #{formatAsDate(purchase_date)}.
We have billed your credit card for #{formatAsMoney(purchase_amount)}.
"""
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Expressive Syntax
3.times { puts “I love Ruby! “ }
stooges = ["Moe", "Larry", "Curly"] # or
stooges = %w(Moe Larry Curly)
country_codes = { 'Thailand' => 'th', 'Singapore' => 'sg' }
['mango', 'pineapple', 'durian'][-1] # “durian”
['mango', 'pineapple', 'durian'].last # “durian”
attr_accessor :id, :name
1_234_567 # 1234567
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Powerful Enumerable Processing
irb(main):001:0> nums = (1..12).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
irb(main):002:0> squares = nums.map { |n| n * n }
=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144]
irb(main):003:0> evens = nums.select { |n| n % 2 == 0 }
=> [2, 4, 6, 8, 10, 12]
irb(main):004:0> odds = nums - evens
=> [1, 3, 5, 7, 9, 11]
irb(main):005:0> sum = nums.inject { |sum,n| sum += n }
=> 78
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Code Block Function Parameters
Functions can have code blocks passed to them as the last argument without explicitly declaring them.
Inside the function, block_given? Can be called to determine the presence/absence of the block.
irb(main):001:0> def foo
irb(main):002:1> if block_given? ; yield; else; puts "No block given."; end
irb(main):003:1> end
irb(main):005:0* foo { puts "I'm passing a block." }
I'm passing a block.
irb(main):006:0> foo
No block given.
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Closures
The puts function is passed the closure (underlined), and has access to the variable name even though name is not in its scope. This makes the code block a closure.
irb(main):008:0> name = 'Joe'
=> "Joe"
irb(main):009:0> 3.times { puts "Hi, #{name}! " }
Hi, Joe!
Hi, Joe!
Hi, Joe!
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Automatic Cleanup or State Restoration Using Closures
File.open('myfile.txt') do |file|
file << 'hi' # do something with the file
end # the file is automatically closed
Dir.chdir('another/dir') do
# do something in that directory
end # chdir's back to the original directory
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Everything’s an Object, Even 1 and nil
irb(main):020:0> 1.class=> Fixnum
irb(main):021:0> [].class=> Array
irb(main):022:0> {}.class=> Hash
irb(main):023:0> //.class=> Regexp
irb(main):024:0> self.class=> Object
irb(main):025:0> nil.class=> NilClass
irb(main):001:0> (0..10).class=> Range
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Ranges
irb(main):004:0> (0..3).class=> Range
irb(main):005:0> (0..3).to_a=> [0, 1, 2, 3]
irb(main):006:0> (0...3).to_a=> [0, 1, 2]
irb(main):007:0> nums = (0..10).to_a=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):008:0> nums[3..5]=> [3, 4, 5]
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Regular Expressions
Can be used as a literal, i.e. without a reference: /^A/
=~ returns an index (or nil if not found).
=== returns a boolean value representing the presence or absence of a match.
Can be used in a case statement, and can simulate multimethods in this way.
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Regular ExpressionLiterals
irb(main):001:0> fruits = %w(apple mango peach pear)
=> ["apple", "mango", "peach", "pear"]
irb(main):002:0> fruits.grep /^p/
=> ["peach", "pear"]
irb(main):003:0> p_regex = /^p/; fruits.grep p_regex
=> ["peach", "pear"]
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Regular ExpressionPresence/Absence Using ===
irb(main):005:0> /^p/ === 'peach'
=> true
irb(main):006:0> /^p/ === 'mango'
=> false
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Regular ExpressionPosition Using =~
irb(main):007:0> 'peach' =~ /c/
=> 3
irb(main):008:0> 'mango' =~ /c/
=> nil
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Regular Expressionsin Case Statements
irb(main):013:0> def test_for_a(word)
irb(main):014:1> case word
irb(main):015:2> when /^a/
irb(main):016:2> puts "#{word} begins with an 'a'."
irb(main):017:2> else
irb(main):018:2* puts "#{word} does *not* begin with an 'a'."
irb(main):019:2> end
irb(main):020:1> end
irb(main):021:0>
irb(main):022:0* test_for_a('mango')
mango does *not* begin with an 'a'.
irb(main):023:0> test_for_a('apple')
apple begins with an 'a'.
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
JRuby
Runs in the Java Virtual Machine.
Leverages existing Java libraries and infrastructure.
Can be a better Java than Java (e.g. provides irb interactive shell).
Unit testing Java code with JRuby (e.g. with rspec) is more flexible and expressive than testing in JUnit.
JRuby can be used to script DB access via JDBC.
jruby-complete.jar contains Jruby and gem, irb, rake, rdoc, ri utilities.
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
JRuby as a Java Shell
Get available locales:import 'java.util.Locale'
Locale.available_locales.each do |locale|
puts locale.display_name
end
Show “os.” System Propertiesimport java.lang.System
os_properties = System.properties.select do
|key, value| /^os./ === key
end
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Operating System Scripting
Ruby’s power and expressiveness can be combined with OS resources and commands:
`find . -name \"*.tmp\" -exec rm {} \";\"`
However, Ruby has its own functions that can substitute for OS commands, enabling scripting that's OS-neutral and easier to read:
Dir.glob('**/*.tmp').each { |f| File.delete f }
Keith Bennett keithrbennett at gmail dot com
What I Love About Ruby19 February 2010
Asian Institute of TechnologyBangkok, Thailand
Metaprogramming
Enables creation of DSL’s (Domain Specific Languages) such as Ruby on Rails
Enables dramatic simplifications, such as attr_accessor
Enables on-the-fly method creation, such as creating accessor methods on elements in a parsed XML file.
The metaprogrammer’s t-shirt says: “I write code that writes code for food.”