defvl_method(first, *others)puts"First is: "+ first.to_sputs"Others: "+ others.to_sendvl_method(1,2)vl_method(1,2,3,4,5,6)
# Variable Length Argumentsdefsum(a,b) a+bend>> sum *[1,2]=>3>> sum *[10,20]=>30
defprintPerson(hash)puts hash["name"]puts hash["age"]endprintPerson({"name"=>"Jon","age"=>25})# Improved:defprintPerson(hash) name = hash[:name] ||'Unknown' name = hash[:age] ||'Unknown' name = hash[:gender] ||'Unknown'print"#{name}#{age}#{gender}"end>> printPerson name:"Jon", age:25=>Jon25Unknown
defmethodputs"uno"yieldputs"dos"yieldend>> method { puts"check!" }unocheck!doscheck!# Another exampledefdouble(x)yield2*xend>> double(5) { |x|puts x }=>10
# Ruby allows you to pass a block as an argument.# With this strategy, the block becomes an instance of the Proc class and you have# to use call instead of yield to transfer the control to it.## To specify that an argument will be a Proc object that encapsulates a block# you must use ampersand (&) in method definition.defsquare_cube(n,&p)for i in1..0p.call(i**2)p.call(i**3)endend>> square_cube(5) { |x|print x,"\s" }1148927166425125>> square_cube(5) { |x|print x-1,"\s" }0037826156324124# Using Proc>> square =Proc.new {|x|print x**2,"\s"}>> (1..10).each(&square)149162536496481100>> summ =Proc.new{|sum,x| sum+x**2}>> (1..5).inject(0,&summ)=>55
Variables and Scope
Variable: name for a mutable value
Ruby is a dynamically typed language, you can create a variable without specifying its type.
4 types: local, global, instance, class.
Ruby allows the definitions of constant too.
# Local scope is the area where code that can use the binding # between the name and the object ref value.
If the outside scope has some binding for variables with the same name used in the block scope, they are hidden inside the block and reactivated outside.
Note that statements like for, while, if, etc... do not define a new scope. Variables defined inside them are still accessible outside.
for i in1..0 a = i +1enda ===11# True
Methods does define its own scope and variables.
Generally, the following control structures define a new scope:
def ... end
class ... end
module ... end
loop {...}
proc {...}
iterators/method blocks
the entire script
You can also verify the scope of a variable using the defined? method.
Global variables begins with the $ special character.
Accessible anywhere in the program.
Nor recommendable. Global vars can be changed anywhere in the code.
Their overuse can make tracking and handling bugs difficult.
$* # array of command line arguments$0 # name of the script being executed$_ # last string reads by gets
Instance and class variables can be defined within a class definition.
Class variables begin with @@and they are visible by all instances of a class.
Instance variables begin with @ and they are local to specific instances of a class.
Constants begin with uppercase letters.
Ruby allows you to change uppercased variables but a warning is raised.
Constants belong to their namespace in their scope:
A=100moduleBA=200end>>A# 100>> B:A# 200
Ruby has a lot of predefined constants:
ARGV: holds command line arguments.
ENV: holds info about the environment.
Some tricks
# Multiple variable assignment>> a,b,c ="a","b","c"# Swap values>> x =10; y =20>> [x, y] = [y, x]# Multi-variable assignment via a functiondefret_valuereturn1,2,3endone, two, three = ret_value