Learning Ruby: Syntax (Part 3)

Methods

  • Ruby functions start with def just like python, but end with end keyword.
  • splat operator (*) to destructure an array into a List. This is similar to Python splat operator
>>> x = [10, 20, 30]
>>> a, *b = x
>>> print(f'{a=}, {b=}')
a=10, b=[20, 30]

Python ☝️, Ruby 👇

>> first, *rest, last  = ["a", "b", "c", "d"]
=> ["a", "b", "c", "d"]
>> first
=> "a"
>> rest
=> ["b", "c"]
>> last
=> "d"
>>

But in Ruby, splat operator can also create an array.

>> q=*135
=> [135]
>> q
=> [135]

In the second scenario1, it creates an array. I think this is useful for scenario where the method accepts either a single element or an array.

In python, we have to write an awkward code like


if isinstance(item, int):
  my_list = [item]
  • When used in method argument, splat operator is similar to python’s *args (args is just a convention)
  • Method name conventions
    • if method ends with ? it returns boolean e.g. 5.even? #=> false
    • if method ends with ! it does something destructive
      • e.g. upcase returns the upper case version of the string, but the string itself does not change
      • But upcase! returns the upper case version of the string, while also changing the string itself to upper case.

classes

  • class definition starts with keyword class just like python. But ends with end keyword.
  • scopes determined by the prefix of the variable name
    • @ : instance scope
    • $ : global scope
    • @@ : class scope
  • class methods start with self. Can not be called on an instance (Like @staticmethod in python ??)
  • Derived class uses < to denote parent class
# Derived class
class Derived < Baseclass
end
  • include and extend
module ModuleExample
  def foo
    'foo'
  end
end

# Including modules binds their methods to the class instances.
# Extending modules binds their methods to the class itself.
class Person
  include ModuleExample
end

class Book
  extend ModuleExample
end

Person.foo     #=> NoMethodError: undefined method `foo' for Person:Class
Person.new.foo #=> "foo"
Book.foo       #=> "foo"
Book.new.foo   #=> NoMethodError: undefined method `foo'
  • Variable that start with Capital letter are constants, BUT constants can change 🤯
  • We get a warning when re-initializing the constant, but that is about it.
irb(main):015:0> Var = "I'm a constant"
=> "I'm a constant"
irb(main):016:0> Var.upcase!
=> "I'M A CONSTANT"
irb(main):017:0> Var
=> "I'M A CONSTANT"
irb(main):018:0> defined? Var
=> "constant"
irb(main):022:0> Var = "I can change"
(irb):22: warning: already initialized constant Var
(irb):19: warning: previous definition of Var was here
  • To make it immutable, call .freeze method
irb(main):001:0> Var = "I can change"
=> "I can change"
irb(main):002:0> Var.freeze
=> "I can change"
irb(main):003:0>  Var.upcase!
(irb):3:in `upcase!': can't modify frozen String: "I can change" (FrozenError)
...
...
...
irb(main):004:0> Var
=> "I can change"

Last Updated: Jan 22, 2022. Added details of how splat operator can also construct an array


  1. I came across this second use here ↩︎