# Ruby has lots of operators, but they're nearly all # methods really ;) The numeric types define the # arithmetic operations as you'd expect: p 3 + 1 p 48.3 - 6 p (18 + 7 * 6) / 2.4 # However, lots of other classes define operators too. # like String (see strings.rb) and arrays... p [1,2,3] + [4,5] p [1,2,3,4,5] - [1,3,5] # There are all the other operators you'd expect too, and # they're all defined via methods # Equality (==) and case comparison (===) are methods class Demo attr_reader :str def initialize(str) @str = str end def ==(other) @str == other.str end def ===(other) @str === other.str end end d1 = Demo.new("str") d2 = Demo.new("str") p d1 == d2 case d1 when d2 p "Case comp match!" end # The square bracket operators can be easily defined class Demo def [](idx) @str[idx] end def []=(idx, value) @str[idx] = value end end p d2[1] d2[1] = 99 p d2[1] puts "Changed str: #{d2.str}" # String brackets are much more flexible than that. E.g. they let # you extract a matching portion: s = 'Test string' puts "Matching portion: #{s['est']}" # and can even be assigned to s['est'] = 'otal' puts "String now #{s}" # Bit of a shock if you're coming from an immutable-string language, # huh? # Many classes define '=~' to match a regexp. Let's go back # and do that for our Demo class. class Demo # adding methods def =~(regexp) @str =~ regexp end end p 'Regex Match!' if d1 =~ /s.r/ # You can even redefine some of the unary operators class Demo def +@ "Positive " + @str end def -@ "Negative " + @str end end puts -d1 puts +d2 # IMHO, One of Ruby's most univerally handy features is the conditional # assignment ('improvement') operators, that allow you to test and set # a variable based on it's existing value (or lack thereof). # # NOTE that these shouldn't be confused with the bitwise assignment # operators (see bitwise.rb). # Firstly, you often need to use a variable, giving it some default value # if it's not yet set. This is easy with: new_var ||= "Default" puts new_var new_var ||= "Won't be assigned" puts new_var # Less often, you'll want to do the opposite - assign only if the variable # already has a value. no_var = nil no_var &&= "Improved" puts no_var new_var &&= "Ahh, that's better..." puts new_var