Ruby is an interpreted language with dynamic typing used for scripting mostly.
puts"hello there"is the hello world
puts"hello, #{1 + 1}"# 2You 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# * Grassputs is simply print with a newline
Get user input:
print"how old are you"age=gets.chompputs"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=ARGVputs"Your first variable is: #{first}"# here, first has the 1st argument for egTo accept input, one should use $stdin.gets.chomp
We can read a file using:
filename=ARGV.first# or file_again = $stdin.gets.chomptxt=open(filename)putstxt.readdeffoo(x)x*2endThe 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
defsurroundputs'{'yieldputs'}'endputssurround{puts'hello world'}#=> {#=> hello world#=> }The block can also be converted to a proc object, which can be called with .call invocation.
defguests(&block)block.class#=> Procblock.call(4)endThe arguments passed to call are given to the block
defguests(&block)block.class#=> Procblock.call(4)endguests{ |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:
defname=(name)@name=nameendBasic initializer:
definitialize(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=ageendBasic getter method
defname@nameendExample:
classFoodefinitialize(name,age=0)@name=nameenddefgetName@nameendendf=Foo.new"Foobar"putsf.getName# FoobarThe getter/setter is such a pattern that there are shortcuts to auto create them:
attr_reader :name
So, this works now:
classFooattr_reader:namedefinitialize(name,age=0)@name=nameenddefgetName@nameendendf=Foo.new"Foobar"putsf.getNameputsf.name# Foobar# FoobarNote, 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:
classPersonattr_reader:namedefinitialize(name)@name=nameenddefname=(name)@name=nameendendjohn=Person.new("John")john.name="Jim"putsjohn.name# => JimIt 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.
classHumandefself.say(msg)putsmsgendendputsHuman.say"hello"# helloVariable’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.
classPersonincludeModuleExampleendExtending modules binds their methods to the class itself.
classBookextendModuleExampleend2+2
The + symbol is just syntactic sugar for the calling the + function on the number
So, these are equivalent
puts2+2puts2.+ 2Note, in ruby, the syntax to call functions is:
fn_name [<arg1> <arg2> ... ]
For loop are like this elsewhere,
forcounterin1..5puts"iteration #{counter}"endIn ruby, they look like this:
(1..5).eachdo |counter|
puts"iteration #{counter}"endThis 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.eachdo |foo|
putsfooend