basic syntax - ut · ruby string syntax • single quotes (only \' and \\) !'bill\'s...
TRANSCRIPT
Basic syntax
RUBY LUCIANO GARCÍA-‐BAÑUELOS
sum = 0 !i = 1 !while i <= 10 do! sum += i*i ! i = i + 1 !end!print "Sum of squares is #{sum}\n"!
No variable declara<ons
Newline is statement separator
do … end instead of { … }
Parenthesis are op<onal in method calls String interpola-on
Ruby string syntax • Single quotes (only \' and \\)
!'Bill\'s "personal" book' "
• Double quotes (many escape sequences) !"Found #{count} errors\nAborting job\n" "
• %q () – similar to simple quotes !%q<Nesting works: <b>Hello</b>> "
• %Q () – similar to double quotes !%Q|She said "#{greeting}"\n| "
• “Here documents” !<<END "!First line "!Second line "!END "
RUBY LUCIANO GARCÍA-‐BAÑUELOS
Variable names and scopes
RUBY LUCIANO GARCÍA-‐BAÑUELOS
foo Local variable $foo Global variable @foo Instance variable in object @@foo Class variable MAX_USERS “Constant” (by conven<on)
Ruby statements
RUBY LUCIANO GARCÍA-‐BAÑUELOS
if x < 10 then! ... !elsif x < 20! ... !else! ... !end!
while x < 10 do ! ... !end!
array = [22, 34, 46, 92] !for value in array do! ... !end!
Literal arrays
Ruby classes
RUBY LUCIANO GARCÍA-‐BAÑUELOS
class Point ! def initialize(x, y) ! @x = x ! @y = y ! end! ! def x ! @x ! end! ! def x=(value) ! @x = value! end!end!
p = Point.new(3,4) !puts "p.x is #{p.x}"!p.x = 44 !
Another example: Binary tree
RUBY LUCIANO GARCÍA-‐BAÑUELOS
class BinaryTree!! def initialize(value = nil) ! @value = value ! @left = @right = nil! end!! def insert(value) ! ... ! end!! def traverse_in_order! @left.traverse_in_order unless @left.nil? ! puts @value unless @value.nil? ! @right.traverse_in_order unless @right.nil? ! end!!end!
Binary tree (cont.)
RUBY LUCIANO GARCÍA-‐BAÑUELOS
class BinaryTree!!
def insert(value) ! if @value.nil? ! @value = value! elsif value < @value! if @left.nil? ! @left = BinaryTree.new(value) ! else ! @left.insert(value) ! end! else! if @right.nil? ! @right = BinaryTree.new(value) ! else ! @right.insert(value) ! end! end! end!!
end!
Let’s play with our example
RUBY LUCIANO GARCÍA-‐BAÑUELOS
tree1 = BinaryTree.new(10) !tree1.insert(5) !tree1.insert(15) !tree1.insert(20) !!tree1.traverse_in_order !
tree2 = BinaryTree.new!input = %w{one two three four five six} !!for w in input !
"tree2.insert(w) !end!!tree2.traverse_in_order !
% notation
RUBY LUCIANO GARCÍA-‐BAÑUELOS
Modifier Meaning
%q[] Non-‐interpolated String (except for \\ \[ and \])
%Q[] Interpolated String (default)
%r[] Interpolated Regexp (flags can appear aYer the closing delimiter)
%i[] Non-‐interpolated Array of symbols, separated by whitespace (aYer Ruby 2.0)
%I[] Interpolated Array of symbols, separated by whitespace (aYer Ruby 2.0)
%w[] Non-‐interpolated Array of words, separated by whitespace
%W[] Interpolated Array of words, separated by whitespace
%x[] Interpolated shell command
Arrays
RUBY LUCIANO GARCÍA-‐BAÑUELOS
x = Array.new # same as x = []!x << 10 " " # same as x.push(10)!!x[0] = 99 !y = ["Alice", 23, 7.3] !x[1] = y[1] + y[-1] !
From the end and downwards
Iterating through arrays
RUBY LUCIANO GARCÍA-‐BAÑUELOS
a = [1,2,3,4,5] !i = 0 !while i < a.length! puts a[i] ! i = i + 1 !end! a = [1,2,3,4,5] !
a.each { |x| puts x } !
Code block Delimited by: { … } or do … end Parameter list body
More examples on code blocks
◦ n.-mes runs code block n <mes ◦ n.upto(m) runs code block for integers n..m ◦ a.find returns first element x of array such that the block returns true for x
◦ a.collect applies block to each element of array and returns new array (a.collect! modifies the original)
RUBY LUCIANO GARCÍA-‐BAÑUELOS
3.times { puts "hello"; puts "goodbye" } !5.upto(10) { |x| puts(x + 1) } ![1,2,3,4,5].find { |y| y % 2 == 0 } ![5,4,3].collect { |x| -x } !(1..10).inject(:*) !
Calling code blocks
RUBY LUCIANO GARCÍA-‐BAÑUELOS
def countx(x)! for i in (1..x)! puts i ! yield! end!end!!countx(4) { puts "foo" }!
>> countx(4) 1 foo 2 foo 3 foo 4 foo => 1..4
Let’s improve our binary tree class
RUBY LUCIANO GARCÍA-‐BAÑUELOS
class BinaryTree!! def traverse(mode = :in_order, &block) ! case mode ! when :in_order! @left.traverse mode, &block unless @left.nil? ! yield @value ! @right.traverse mode, &block unless @right.nil? ! when :pre_order! ... ! when :post_order! ... ! end! end !!end!
Let’s play again with our example
RUBY LUCIANO GARCÍA-‐BAÑUELOS
tree1 = BinaryTree.new![10,20,15,5].each {|x| tree1.insert(x)} !tree1.traverse { |x| puts x }!
tree2 = BinaryTree.new!%w{one two three four five six}.each{ |w| tree2.insert(w) } !!tree2.traverse(:in_order) { |x| print " #{x}" }; puts !tree2.traverse(:pre_order) { |x| print " #{x}" }; puts !tree2.traverse(:post_order) { |x| print " #{x}" }; puts !
Hashes
RUBY LUCIANO GARCÍA-‐BAÑUELOS
person = Hash.new"# same as person = {}!!person["last_name"] = "Rodriguez"!person[:first_name] = "Alice"!order = {"item" => "Corn Flakes", "weight" => 18} !order = {:item => "Corn Flakes", :weight => 18} !order = {item: "Corn Flakes", weight: 18} !
Ruby Luciano García-‐Bañuelos
Regular Expressions • A way of describing pamerns or sets of strings ◦ Searching and matching ◦ Formally describing strings
◦ The symbols (lexemes or tokens) that make up a language
• Common to lots of languages and tools ◦ awk, sed, perl, grep, Java, OCaml, C libraries, etc.
• Based on some really elegant theory ◦ We’ll see that soon
Ruby Luciano García-‐Bañuelos
Example Regular Expressions in Ruby
• /Ruby/ ◦ Matches exactly the string "Ruby" ◦ Regular expressions can be delimited by /’s ◦ Use \ to escape /’s in regular expressions
• /(Ruby|OCaml|Java)/ ◦ Matches either "Ruby", "OCaml", or "Java"
• /(Ruby|Regular)/ or /R(uby|egular)/ ◦ Matches either "Ruby" or "Regular" ◦ Use ()’s for grouping; use \ to escape ()’s
Ruby Luciano García-‐Bañuelos
Repetition in Regular Expressions
• /(Ruby)*/ ◦ {"", "Ruby", "RubyRuby", "RubyRubyRuby", ...} ◦ * means zero or more occurrences
• /(Ruby)+/ ◦ {"Ruby", "RubyRuby", "RubyRubyRuby", ... } ◦ + means one or more occurrence ◦ so /e+/ is the same as /ee*/
Ruby Luciano García-‐Bañuelos
Repetition in Regular Expressions
• /(Ruby)?/ ◦ {"", "Ruby"} ◦ ? means op,onal, i.e., zero or one occurrence
• /(Ruby){3}/ ◦ {“RubyRubyRuby”, “RubyRubyRubyRuby”, …} ◦ {x} means repeat the search for at least x occurrences
• /(Ruby){3, 5}/ ◦ {“RubyRubyRuby”, “RubyRubyRubyRuby”, “RubyRubyRubyRubyRuby”} ◦ {x, y} means repeat the search for at least x occurrences and at most y occurrences
Ruby Luciano García-‐Bañuelos
Watch Out for Precedence • /(Ruby)*/ means {"", "Ruby", "RubyRuby", ...} ◦ But /Ruby*/ matches {"Rub", "Ruby", "Rubyy", ...}
• In general ◦ * {n} and + bind most <ghtly ◦ Then concatena<on (adjacency of regular expressions) ◦ Then |
• Best to use parentheses to disambiguate
Ruby Luciano García-‐Bañuelos
Character Classes • /[abcd]/ ◦ {"a", "b", "c", "d"} (Can you write this another way?)
• /[a-‐zA-‐Z0-‐9]/ ◦ Any upper or lower case lemer or digit
• /[^0-‐9]/ ◦ Any character except 0-‐9 (the ^ is like not and must come first)
• /[\t\n ]/ ◦ Tab, newline or space
• /[a-‐zA-‐Z_\$][a-‐zA-‐Z_\$0-‐9]*/ ◦ Java iden<fiers ($ escaped...see next slide)
Ruby Luciano García-‐Bañuelos
Special Characters . any character ^ beginning of line $ end of line \$ just a $ \d digit, [0-‐9] \s whitespace, [\t\r\n\f] \w word character, [A-‐Za-‐z0-‐9_] \D non-‐digit, [^0-‐9] \S non-‐space, [^\t\r\n\f] \W non-‐word, [^A-‐Za-‐z0-‐9_]
Ruby Luciano García-‐Bañuelos
Potential Character Class Confusions ^ inside character classes: not outside character classes: beginning of line [] inside regular expressions: character class outside regular expressions: array note: [a-‐z] does not make a valid array, () inside character classes: literal characters ( ( /(0..2)/ does not mean 012 outside character classes: used for grouping - inside character classes: range (e.g., a to z given by [a-‐z]) outside character classes: dash
Using regular expressions
RUBY LUCIANO GARCÍA-‐BAÑUELOS
line = gets # read line from standard input!if line =~ /Ruby/ then # returns nil if not found! puts "Found Ruby"!end!
gets =~ /^Min: (\d+) Max: (\d+)$/ !min, max = $1, $2 !
def m(s)! s =~ /(Foo)/ ! puts $1 # prints Foo!end!m("Foo")!puts $1 # prints nil!
Finally … metaprogramming
RUBY LUCIANO GARCÍA-‐BAÑUELOS
class Polyglot ! def initialize ! @@greetings = {estonian: "Tere hommikust", english: "Good morning"} ! end! def add_language(language, greeting) ! @@greetings[language] = greeting if language.is_a? Symbol ! end! def method_missing(name) ! unless @@greetings[name].nil? ! puts @@greetings[name] ! else! super! end! end!end!!a = Polyglot.new!!a.estonian!a.english!