Learning Ruby

1,327 views
1,253 views

Published on

A slide presentation I gave at OSCON 2007 in Portland, Oregon on the Ruby programming language.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,327
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
42
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Learning Ruby

  1. 1. Learning Ruby Mike Fitzgerald OSCON 2007
  2. 2. <ul><li>Thank you“Matz” Matsumoto Yukihiro </li></ul>
  3. 3. Today’s schedule <ul><li>8:30–9:40 AM : Instruction (70 minutes) </li></ul><ul><li>9:40–9:50 AM : Break (10 minutes) </li></ul><ul><li>9:50–11:00 AM : Instruction (70 minutes) </li></ul><ul><li>11:00–11:10 AM : Break (10 minutes) </li></ul><ul><li>11:10 AM– 12 noon: Instruction (50 minutes) </li></ul>
  4. 4. Ruby history <ul><li>Matz had wanted to create his own language since high school </li></ul><ul><li>Development started in 1993 </li></ul><ul><li>First release was in 1995 (same time as Java) </li></ul><ul><li>Emerged in the West around 2000 </li></ul><ul><li>Ruby on Rails brought it wide attention in 2004 </li></ul>
  5. 5. What is Ruby? <ul><li>Object-oriented scripting language </li></ul><ul><li>Open source </li></ul><ul><li>Mature and stable </li></ul><ul><li>Complex language with a simple syntax </li></ul>
  6. 6. What is Ruby? continued <ul><li>Interpreted rather than compiled </li></ul><ul><li>Core written in C </li></ul><ul><li>Can write C extensions, too </li></ul><ul><li>Borrows ideas from Lisp, Perl, Smalltalk, etc. </li></ul>
  7. 7. Numbers <ul><li>Numbers are not primitives but objects </li></ul><ul><li>Most operators are methods </li></ul><ul><li>No declarations or static types </li></ul><ul><li>Dynamic typing </li></ul><ul><li>Duck typing, a kind of dynamic typing </li></ul>
  8. 8. Numbers continued <ul><li>No increment (++) or decrement (--) operators in Ruby </li></ul><ul><li>Abbreviated assignment operators, such as +=, -=, *=, etc. </li></ul><ul><li>Underscores ignored ( 1_000_000 ) </li></ul><ul><li>Ranges: 1..10 (inclusive) or 2...5 (exclusive) </li></ul><ul><li>Math module: Math.sqrt , Math.sin , etc. </li></ul>
  9. 9. <ul><li>$ which ruby # [Li|U]nix only </li></ul><ul><li>/usr/local/bin/ruby </li></ul><ul><li>$ ruby --version </li></ul><ul><li>ruby 1.8.6 (2007-03-13 patchlevel 0) [powerpc-darwin8.9.0] </li></ul><ul><li>$ irb # Interactive Ruby </li></ul><ul><li>irb(main):001:0> </li></ul>
  10. 10. <ul><li>Running a Ruby program (Windows, [Li|U]nix]) </li></ul>
  11. 11. <ul><li>$ ruby hello.rb </li></ul>
  12. 12. <ul><li>“ Hello, world” </li></ul><ul><li>or </li></ul><ul><li>Printing a string to standard output </li></ul>
  13. 13. <ul><li>print &quot;Good morning!&quot; </li></ul>
  14. 14. <ul><li>puts &quot;Hello, Portland.&quot; </li></ul>
  15. 15. <ul><li>Comments </li></ul>
  16. 16. <ul><li># say hello </li></ul><ul><li>puts &quot;Hello!&quot; </li></ul>
  17. 17. <ul><li>puts &quot;Hello!&quot; # say hello </li></ul>
  18. 18. <ul><li>Block comments </li></ul>
  19. 19. <ul><li>=begin </li></ul><ul><li>Say hello to all the </li></ul><ul><li>nice people out there. </li></ul><ul><li>=end </li></ul><ul><li>puts &quot;Hello!&quot; </li></ul>
  20. 20. <ul><li>Concatenating strings </li></ul>
  21. 21. <ul><li>print &quot;I like &quot; , &quot;trees.&quot; </li></ul>
  22. 22. <ul><li>puts &quot;I like &quot; + &quot;sushi.&quot; </li></ul>
  23. 23. <ul><li>puts &quot;I like &quot; << &quot;Powell’s.&quot; </li></ul>
  24. 24. <ul><li>Shebang ([Li|U]nix) </li></ul>
  25. 25. <ul><li>#!/usr/bin/env ruby </li></ul><ul><li>puts &quot;Hello!&quot; </li></ul>
  26. 26. <ul><li>$ chmod 755 hello.rb </li></ul><ul><li>$ hello.rb </li></ul>
  27. 27. <ul><li>Inserting shell output using backticks </li></ul>
  28. 28. <ul><li>puts &quot;Running &quot; + `ruby -v` </li></ul>
  29. 29. <ul><li>Issuing a system (shell) command </li></ul>
  30. 30. <ul><li>system &quot;echo 'Hello, Matz!'&quot; </li></ul>
  31. 31. <ul><li>Evaluating an expression </li></ul>
  32. 32. <ul><li>eval &quot;puts 'Hi there.'&quot; </li></ul>
  33. 33. <ul><li>$ ruby -e &quot;puts 'Hi there.'&quot; </li></ul>
  34. 34. <ul><li>Multiplicity </li></ul>
  35. 35. <ul><li>puts &quot;Go!&quot; * 3 </li></ul>
  36. 36. <ul><li>3.times { print &quot;Go! &quot; } </li></ul>
  37. 37. Variables <ul><li>Local variable: start with lowercase letter or _ </li></ul><ul><li>Instance variables in class: @name </li></ul><ul><li>Class variables: @@times </li></ul><ul><li>Global variables: $amount </li></ul>
  38. 38. <ul><li>hello = &quot;Hello, universe!&quot; </li></ul><ul><li>puts hello </li></ul>
  39. 39. <ul><li>good = &quot;Guten &quot; </li></ul><ul><li>day = &quot;Tag&quot; </li></ul><ul><li>puts good + day </li></ul>
  40. 40. <ul><li>x = 9 </li></ul><ul><li>y = 18 </li></ul><ul><li>puts x + y </li></ul>
  41. 41. <ul><li>Parallel assignment </li></ul>
  42. 42. <ul><li>x, y = 37, 63 </li></ul>
  43. 43. <ul><li>a, b, c = &quot;15&quot;, &quot;tons&quot;, &quot;200.0&quot; </li></ul>
  44. 44. <ul><li>c, d = 15, &quot;tons&quot; </li></ul>
  45. 45. Symbols <ul><li>Special object in Ruby </li></ul><ul><li>Placeholders for identifiers and strings </li></ul><ul><li>Begin with colon (:) </li></ul><ul><li>Not directly created through assignment </li></ul><ul><li>Efficient: Only one copy held in a single memory address </li></ul>
  46. 46. <ul><li>name = &quot;Javert&quot; </li></ul><ul><li>name. to_sym # => :Javert </li></ul>
  47. 47. <ul><li>:Javert.id2name # => &quot;Javert&quot; </li></ul><ul><li>name == :Javert.id2name # true </li></ul>
  48. 48. <ul><li>Expression substitution </li></ul>
  49. 49. <ul><li>x, y = 37, 63 </li></ul><ul><li>puts #{x + y} </li></ul>
  50. 50. <ul><li>name = &quot;guy&quot; </li></ul><ul><li>puts &quot;Hi, #{name} !&quot; </li></ul>
  51. 51. <ul><li>Retrieving command-line arguments </li></ul>
  52. 52. <ul><li>#!/usr/bin/env ruby </li></ul><ul><li>puts &quot;Hello, #{ ARGV[0] }!&quot; </li></ul>
  53. 53. <ul><li>$ arg.rb everybody </li></ul>
  54. 54. <ul><li>Formatting output </li></ul>
  55. 55. <ul><li>sprintf ( &quot;Hello, %s !&quot;, &quot;Tim&quot; ) </li></ul>
  56. 56. <ul><li>printf ( &quot;Hello, %s !&quot;, &quot;Sam&quot; ) </li></ul>
  57. 57. <ul><li>hi = &quot;Hello, %s &quot; </li></ul><ul><li>puts hi % &quot;people!&quot; </li></ul>
  58. 58. <ul><li>&quot; %s, %s !&quot; % [ &quot;Hello&quot;, &quot;Tim&quot; ] </li></ul>
  59. 59. <ul><li>Getting input from the prompt </li></ul>
  60. 60. <ul><li>#!/usr/bin/env ruby </li></ul><ul><li>print &quot;Say hello to...&quot; </li></ul><ul><li>hi = gets </li></ul><ul><li>puts &quot;Hello, &quot; + hi </li></ul>
  61. 61. <ul><li>$ get.rb </li></ul>
  62. 62. <ul><li>Define and call a method </li></ul>
  63. 63. <ul><li>def hello </li></ul><ul><li>puts &quot;Hello&quot; </li></ul><ul><li>end </li></ul><ul><li>hello </li></ul>
  64. 64. <ul><li>Aliasing a method </li></ul>
  65. 65. <ul><li>alias hi hello </li></ul><ul><li>hi </li></ul>
  66. 66. <ul><li>Undefining a method </li></ul>
  67. 67. <ul><li>undef hello </li></ul>
  68. 68. <ul><li>Defining a method with an argument </li></ul>
  69. 69. <ul><li>def hello ( who ) </li></ul><ul><li>puts &quot;Hello &quot; + who + &quot;.&quot; </li></ul><ul><li>end </li></ul><ul><li>hello &quot;Yuri&quot; </li></ul>
  70. 70. <ul><li>def repeat ( word, times ) </li></ul><ul><li>puts word * times </li></ul><ul><li>end </li></ul><ul><li>repeat &quot;Go! &quot;, 3 </li></ul>
  71. 71. <ul><li>Return a value explicitly </li></ul>
  72. 72. <ul><li>def hello </li></ul><ul><li>return &quot;Hello.&quot; </li></ul><ul><li>end </li></ul>
  73. 73. <ul><li>Defining a method with a default value for an argument </li></ul>
  74. 74. <ul><li>def hello ( who=&quot;Schlomo&quot; ) </li></ul><ul><li>puts &quot;Hello &quot; + who + &quot;.&quot; </li></ul><ul><li>end </li></ul><ul><li>hello </li></ul>
  75. 75. <ul><li>Defining a method with a variable number of arguments </li></ul>
  76. 76. <ul><li>def hello( *args ) </li></ul><ul><li>puts args.size </li></ul><ul><li>end </li></ul>
  77. 77. <ul><li>def two_plus( one, two, *args ) </li></ul><ul><li>length = args.size </li></ul><ul><li>label = length == 1 ? &quot; variable argument&quot; : &quot; variable arguments&quot; </li></ul><ul><li>num = length.to_s + label + &quot; (&quot; + args.inspect + &quot;)&quot; </li></ul><ul><li>num </li></ul><ul><li>end </li></ul><ul><li>puts two_plus( 1, 2 ) </li></ul>
  78. 78. <ul><li>Yielding a block </li></ul>
  79. 79. <ul><li>def hello </li></ul><ul><li>yield </li></ul><ul><li>end </li></ul><ul><li>hello { puts &quot;Hello, Matz.&quot; } </li></ul>
  80. 80. <ul><li>Defining and calling a procedure (proc) </li></ul>
  81. 81. <ul><li>proc = lambda { puts &quot;Hello!&quot; } </li></ul><ul><li>proc.call </li></ul>
  82. 82. <ul><li>Calling the each method </li></ul>
  83. 83. <ul><li>[&quot;Hi&quot;,&quot;Mel&quot;]. each {|e| print e} </li></ul>
  84. 84. <ul><li>XML </li></ul>
  85. 85. <ul><li><hello>there!</hello> </li></ul>
  86. 86. <ul><li>#!/usr/bin/env ruby </li></ul><ul><li>require &quot;rexml/document&quot; </li></ul><ul><li>file = File.new( &quot;hello.xml &quot; ) </li></ul><ul><li>doc = REXML::Document.new file </li></ul><ul><li>puts doc.to_s </li></ul>
  87. 87. <ul><li>Conditional statements </li></ul>
  88. 88. <ul><li>if </li></ul>
  89. 89. <ul><li>x, y = 45, 32 </li></ul><ul><li>if x > y then </li></ul><ul><li>puts &quot;x is greater than y&quot; </li></ul><ul><li>end </li></ul>
  90. 90. <ul><li>if hi == false : puts &quot;Goodbye&quot; end </li></ul>
  91. 91. <ul><li>if hi == true </li></ul><ul><li>puts &quot;Hi&quot; </li></ul><ul><li>end </li></ul>
  92. 92. <ul><li>if ! hi == false </li></ul><ul><li>puts &quot;Hello!&quot; </li></ul><ul><li>end </li></ul>
  93. 93. <ul><li>Multiple tests </li></ul>
  94. 94. <ul><li>if ruby==&quot;nifty&quot; && programming==&quot;fun&quot; </li></ul><ul><li>puts &quot;Keep programming!&quot; </li></ul><ul><li>end </li></ul>
  95. 95. <ul><li>if ruby==&quot;nifty&quot; and programming==&quot;fun&quot; </li></ul><ul><li>puts &quot;Keep programming!&quot; </li></ul><ul><li>end </li></ul>
  96. 96. <ul><li>if a == 10 || b == 27 </li></ul><ul><li>print a + b </li></ul><ul><li>end </li></ul>
  97. 97. <ul><li>if a == 10 or b == 27 </li></ul><ul><li>print a + b </li></ul><ul><li>end </li></ul>
  98. 98. <ul><li>Statement modifier for if </li></ul>
  99. 99. <ul><li>puts &quot;x is less than y&quot; if x < y </li></ul>
  100. 100. <ul><li>Using else </li></ul>
  101. 101. <ul><li>if x >= y </li></ul><ul><li>puts &quot;x greater than or equal to y&quot; </li></ul><ul><li>else </li></ul><ul><li>puts &quot;x not greater than or equal to y&quot; </li></ul><ul><li>end </li></ul>
  102. 102. <ul><li>Using elseif </li></ul>
  103. 103. <ul><li>if x == y </li></ul><ul><li>puts &quot;x equals y&quot; </li></ul><ul><li>elsif x != y </li></ul><ul><li>puts &quot;x is not equal to y&quot; </li></ul><ul><li>elsif x > y </li></ul><ul><li>puts &quot;x is greater than y&quot; </li></ul><ul><li>elsif x < y </li></ul><ul><li>puts &quot;x is less than y&quot; </li></ul><ul><li>elsif x >= y </li></ul><ul><li>puts &quot;x is greater than or equal to y&quot; </li></ul><ul><li>elsif x <= y </li></ul><ul><li>puts &quot;x is less than or equal to y&quot; </li></ul><ul><li>else </li></ul><ul><li>puts &quot;Arrrrgh!&quot; </li></ul><ul><li>end </li></ul>
  104. 104. <ul><li>Using the colon </li></ul>
  105. 105. <ul><li>lang = &quot;de&quot; </li></ul><ul><li>if lang == &quot;en&quot;: print &quot;dog&quot; </li></ul><ul><li>elsif lang == &quot;es&quot;: print &quot;perro&quot; </li></ul><ul><li>elsif lang == &quot;fr&quot;: print &quot;chien&quot; </li></ul><ul><li>elsif lang == &quot;de&quot;: print &quot;Hund&quot; </li></ul><ul><li>else puts &quot;dog&quot; </li></ul><ul><li>end </li></ul>
  106. 106. <ul><li>The negated form of if: unless </li></ul>
  107. 107. <ul><ul><ul><li>if lang == &quot;de&quot; </li></ul></ul></ul><ul><ul><ul><li>dog = &quot;Hund&quot; </li></ul></ul></ul><ul><ul><ul><li>else </li></ul></ul></ul><ul><ul><ul><li>dog = &quot;dog&quot; </li></ul></ul></ul><ul><ul><ul><li>end </li></ul></ul></ul>
  108. 108. <ul><li>unless lang == &quot;de&quot; </li></ul><ul><li>dog = &quot;dog&quot; </li></ul><ul><li>else </li></ul><ul><li>dog = &quot;Hund&quot; </li></ul><ul><li>end </li></ul>
  109. 109. <ul><li>Statement modifier for unless </li></ul>
  110. 110. <ul><li>puts num += 1 unless num > 88 </li></ul>
  111. 111. <ul><li>while </li></ul>
  112. 112. <ul><li>i = 0 </li></ul><ul><li>breeds = [ &quot;quarter&quot;, &quot;arabian&quot;, &quot;appaloosa&quot;, &quot;paint&quot; ] </li></ul><ul><li>puts breeds.size # => 4 </li></ul><ul><li>temp = [] </li></ul><ul><li>while i < breeds.size do </li></ul><ul><li>temp << breeds[i].capitalize </li></ul><ul><li>i +=1 </li></ul><ul><li>end </li></ul>
  113. 113. <ul><li>temp.sort! # => [&quot;Appaloosa&quot;, &quot;Arabian&quot;, &quot;Paint&quot;, &quot;Quarter&quot;] </li></ul><ul><li>breeds.replace( temp ) </li></ul><ul><li>p breeds # => [&quot;Appaloosa&quot;, &quot;Arabian&quot;, &quot;Paint&quot;, &quot;Quarter&quot;] </li></ul>
  114. 114. <ul><li>temp = 98.3 </li></ul><ul><li>begin </li></ul><ul><li>print &quot;Your temperature is &quot; + temp.to_s + &quot; Fahrenheit. &quot; </li></ul><ul><li>puts &quot;I think you're okay.&quot; </li></ul><ul><li>temp += 0.1 </li></ul><ul><li>end while temp < 98.6 </li></ul>
  115. 115. <ul><li>while i < breeds.size </li></ul><ul><li>temp << breeds[i].capitalize </li></ul><ul><li>break if temp[i] == &quot;Arabian&quot; </li></ul><ul><li>i +=1 </li></ul><ul><li>end </li></ul><ul><li>p temp # => [&quot;Quarter&quot;, &quot;Arabian&quot;] </li></ul>
  116. 116. <ul><li>Statement modifier for while </li></ul>
  117. 117. <ul><li>cash = 100_000.00 </li></ul><ul><li>sum = 0 </li></ul><ul><li>cash += 1.00, sum while cash < 1_000_000.00 # _ ignored </li></ul>
  118. 118. <ul><li>The negated form of while: until </li></ul>
  119. 119. <ul><li>weight = 150 </li></ul><ul><li>while weight < 200 do </li></ul><ul><li>puts &quot;Weight: &quot; + weight.to_s </li></ul><ul><li>weight += 5 </li></ul><ul><li>end </li></ul>
  120. 120. <ul><li>weight = 150 </li></ul><ul><li>until weight == 200 do </li></ul><ul><li>puts &quot;Weight: &quot; + weight.to_s </li></ul><ul><li>weight += 5 </li></ul><ul><li>end </li></ul>
  121. 121. <ul><li>weight = 150 </li></ul><ul><li>begin </li></ul><ul><li>puts &quot;Weight: &quot; + weight.to_s </li></ul><ul><li>weight += 5 </li></ul><ul><li>end until weight == 200 </li></ul>
  122. 122. <ul><li>Statement modifier for until </li></ul>
  123. 123. <ul><li>puts age += 1 until age > 28 </li></ul>
  124. 124. <ul><li>case </li></ul>
  125. 125. <ul><li>lang = :de </li></ul><ul><li>dog = case lang </li></ul><ul><li>when :en: &quot;dog&quot; </li></ul><ul><li>when :es: &quot;perro&quot; </li></ul><ul><li>when :fr: &quot;chien&quot; </li></ul><ul><li>when :de: &quot;Hund&quot; </li></ul><ul><li>else &quot;dog&quot; </li></ul><ul><li>end </li></ul>
  126. 126. <ul><li>With ranges </li></ul>
  127. 127. <ul><li>scale = 8 </li></ul><ul><li>case scale </li></ul><ul><li>when 0: puts &quot;lowest&quot; </li></ul><ul><li>when 1..3: puts &quot;medium-low&quot; </li></ul><ul><li>when 4..5: puts &quot;medium&quot; </li></ul><ul><li>when 6..7: puts &quot;medium-high&quot; </li></ul><ul><li>when 8..9: puts &quot;high&quot; </li></ul><ul><li>when 10: puts &quot;highest&quot; </li></ul><ul><li>else puts &quot;off scale&quot; </li></ul><ul><li>end </li></ul>
  128. 128. <ul><li>Ternary operator </li></ul>
  129. 129. <ul><li>def two_plus( one, two, *args ) </li></ul><ul><li>length = args.size </li></ul><ul><li>label = length == 1 ? &quot; variable argument&quot; : &quot; variable arguments&quot; </li></ul><ul><li>num = length.to_s + label + &quot; (&quot; + args.inspect + &quot;)&quot; </li></ul><ul><li>num </li></ul><ul><li>end </li></ul><ul><li>puts two_plus( 1, 2 ) </li></ul>
  130. 130. <ul><li>for loop </li></ul>
  131. 131. <ul><li>for i in 1..10 do print i, &quot; &quot; end </li></ul><ul><li># => 1 2 3 4 5 6 7 8 9 10 </li></ul>
  132. 132. <ul><li>upto method </li></ul>
  133. 133. <ul><li>1. upto (10) { |i| print i, &quot; &quot; } </li></ul>
  134. 134. <ul><li>downto mehtod </li></ul>
  135. 135. <ul><li>10. downto (1) {|i| print i,&quot; &quot; } </li></ul>
  136. 136. Classes <ul><li>Almost everything is an object </li></ul><ul><li>Instance variables and methods </li></ul><ul><li>Class variables and methods </li></ul><ul><li>Single inheritance only </li></ul><ul><li>Classes are open, even built-in classes </li></ul>
  137. 137. <ul><li>class Hello </li></ul><ul><li>def initialize ( name ) </li></ul><ul><li>@name = name </li></ul><ul><li>end </li></ul><ul><li>def hi </li></ul><ul><li>puts &quot;Hello, &quot;+ @name +&quot;!&quot; </li></ul><ul><li>end </li></ul><ul><li>end </li></ul>
  138. 138. <ul><li>hello = Hello.new( &quot;Matz!&quot; ) </li></ul><ul><li>hello.hi </li></ul>
  139. 139. Modules <ul><li>Module hold method definitions, etc. </li></ul><ul><li>You cannot instantiate modules </li></ul><ul><li>But you can include (mixin) modules </li></ul><ul><li>Methods, etc., are implemented in modules but never available until mixed in </li></ul><ul><li>Bridge between single and multiple inheritance </li></ul>

×