Ruby is an interpreted language with dynamic typing used for scripting mostly.
puts "hello there"
is the hello world
puts "hello, #{1 + 1}"
# 2
You can put expressions inside the `#{}` and they will be evaluated.
days = "Mon Tue Wed Thu Fri Sat Sun"
puts "Here are the days: #{days}"
Use triple quotes to write multiline strings.
fat_cat = """
I'll do a list:
\t* Cat food
\t* Fishies
\t* Catnip\n\t* Grass
"""
# this will print
# I'll do a list:
# * Cat food
# * Fishies
# * Catnip
# * Grass
puts
is simply print
with a newline
Get user input:
print "how old are you"
age = gets.chomp
puts "okay so you are #{age} years old"
You can convert the string to integer using
age = gets.chomp.to_i
, similarly, to_f
makes it a float
You can accept the arguments from the user
first, second, third = ARGV
puts "Your first variable is: #{first}" # here, first has the 1st argument for eg
To accept input, one should use $stdin.gets.chomp
We can read a file using:
filename = ARGV.first # or file_again = $stdin.gets.chomp
txt = open(filename)
puts txt.read
def foo(x)
x*2
end
The last statement is the return type.
Calling is foo 2
, or foo(2)
Recall what blocks are, they are a block of code, that can be executed.
All methods accept an implicit block. You can insert it whereever needed with the yield
keyword
def surround
puts '{'
yield
puts '}'
end
puts surround { puts 'hello world' }
#=> {
#=> hello world
#=> }
The block can also be converted to a proc
object, which can be called with .call
invocation.
def guests(&block)
block.class #=> Proc
block.call(4)
end
The arguments passed to call are given to the block
def guests(&block)
block.class #=> Proc
block.call(4)
end
guests { |n| "You have #{n} guests." }
# => "You have 4 guests."
By convention, all methods that return booleans end with a question mark.
By convention, if a method name ends with an exclamation mark, it does something destructive like mutate the receiver. Many methods have a ! version to make a change, and a non-! version to just return a new changed version.
Like we saw in reverse!
Classes can be defined with a class
keyword.
There are:
- class variables
@@foo
, which are shared by all instances of this class. - instance variables
@foo
, which can be initialized anywhere, belong to the particular instance of the class
Basic setter:
def name=(name)
@name = name
end
Basic initializer:
def initialize(name, age = 0)
# Assign the argument to the 'name' instance variable for the instance.
@name = name
# If no age given, we will fall back to the default in the arguments list.
@age = age
end
Basic getter method
def name
@name
end
Example:
class Foo
def initialize(name, age=0)
@name = name
end
def getName
@name
end
end
f = Foo.new "Foobar"
puts f.getName
# Foobar
The getter/setter is such a pattern that there are shortcuts to auto create them:
attr_reader :name
So, this works now:
class Foo
attr_reader :name
def initialize(name, age=0)
@name = name
end
def getName
@name
end
end
f = Foo.new "Foobar"
puts f.getName
puts f.name
# Foobar
# Foobar
Note, when I call f.name = "bar"
, I am actually doing f.name=("bar")
aka f.name= "bar"
So I better have a method called name=
Another example:
class Person
attr_reader :name
def initialize(name)
@name = name
end
def name=(name)
@name = name
end
end
john = Person.new("John")
john.name = "Jim"
puts john.name # => Jim
It can also be a single line attr_accessor :name
A class method uses self to distinguish from instance methods. It can only be called on the class, not an instance.
class Human
def self.say(msg)
puts msg
end
end
puts Human.say "hello"
# hello
Variable’s scopes are defined by the way we name them. Variables that start with $ have global scope.
$var = "I'm a global var"
defined? $var #=> "global-variable"
Variables that start with @ have instance scope.
@var = "I'm an instance var"
defined? @var #=> "instance-variable"
Variables that start with @@ have class scope.
@@var = "I'm a class var"
defined? @@var #=> "class variable"
Variables that start with a capital letter are constants.
Var = "I'm a constant"
defined? Var #=> "constant"
Including modules binds their methods to the class instances.
class Person
include ModuleExample
end
Extending modules binds their methods to the class itself.
class Book
extend ModuleExample
end
2+2
The +
symbol is just syntactic sugar for the calling the +
function on the number
So, these are equivalent
puts 2+2
puts 2.+ 2
Note, in ruby, the syntax to call functions is:
fn_name [<arg1> <arg2> ... ]
For loop are like this elsewhere,
for counter in 1..5
puts "iteration #{counter}"
end
In ruby, they look like this:
(1..5).each do |counter|
puts "iteration #{counter}"
end
This is a block. The ‘each’ method of a range runs the block once for each element of the range. The block is passed a counter as a parameter.
The lambda nature of blocks is more easily visible by alternative equivalent form:
(1..5).each { |counter| puts "iteration #{counter}" }
But the general syntax to follow is:
array.each do |foo|
puts foo
end