About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, Thailand Obligatory Joke, Part 1 A DBA walks into a bar, steps in front of two tables and says...
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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.
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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!”
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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; } • Ruby minuendList – subtrahendList
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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)}. """
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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.
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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!
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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.
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, Thailand Regular Expression Presence/Absence Using === irb(main):005:0> /^p/ === 'peach' => true irb(main):006:0> /^p/ === 'mango' => false
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, Thailand Regular Expression Position Using =~ irb(main):007:0> 'peach' =~ /c/ => 3 irb(main):008:0> 'mango' =~ /c/ => nil
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, Thailand Regular Expressions in 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'.
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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.
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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 Properties import java.lang.System os_properties = System.properties.select do |key, value| /^os./ === key end
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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 }
About Ruby 19 February 2010 Asian Institute of Technology Bangkok, 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.”