First example of using ruby


=begin
First Ruby examples for CSCi 4651
=end

# output: 
puts 'Hello World'
# or just p:
p 'Hello World'

# everything is a class
puts 'Hello World'.class #two kinds of strings: '...' and "..." 
                         # '...' are more efficient
puts 5.class
puts 6.5 .class
puts 1/2
puts 1234576879809812346576877890.class
puts (1/2).class
puts 5.class.class # the class of a class is Class
puts self.class # the class of the current object (main)

# variables do not need declaration and don't have a fixed type
# note that names that start with @ and @@ are used as instance 
# and class variable names, respectivelly - do not use them as 
# local variables
n = 5;
puts n
n = 'Hi there'
puts n
puts n != n
puts (n != n).class

m = '55'
# Doesn't work: n = m + 2 
# m is a string
n = m.to_i + 2
puts n

# special object
puts nil
puts nil.class

# single quotes vs double quotes
puts "#{n} little monkeys jumping on the bed"
puts '#{n} little monkeys jumping on the bed'

# conditionals
# the syntax: if...else...end, where else is optional
if (n == 5)
  puts '5 is my favorite number'
else
  puts "#{n} is not my favorite number"
  n = 5
end
puts "n = #{n}"

# unless 
unless n == m
  puts "#{n} != #{m}" 
end
# conditional modifier
puts "n = #{n}" if n < 10
n = 10
puts "n = #{n}" if n < 10
puts "#{n} is a small number" unless n > 10

# loops
while n > 0
  puts n
  n = n/2
end

sum = 0
until sum >= 20
  r = rand(10)
  puts "my random number #{r}"
  sum += r
  puts "the sum is #{sum}"
end

# for loop uses an iterator
# .times is a method of an integer 
3.times do
  puts 'Hello! '
end

# you can name the loop variable if you need it
puts "a loop with a variable"
5.times do |i|
  puts i
end

puts "a step loop"
1.step(10,2) {|k| puts k}
#
# Some interesting types:
#

# ranges
puts "ranges..."
range1 = (1..5)
puts range1.max
# by convention boolean methods end with a ?
puts range1.include?(7)
puts range1.include?(3.5)
# same thing as an operator:
puts range1 === 7
puts range1 === 3.5

digits = (0...10)  #doesn't include 10
puts digits.max
puts digits.min

puts "a for loop with a range"
for i in digits
  puts i
end

puts "a better loop for a range"
digits.each {|j| puts j} 

# arrays
arr1 = [3, 4, 5, 7]
puts arr1[3]
puts "traversing arrays with a loop"
arr1.each {|j| puts j}

arr2 = [2, 3.5, 'yes', "n = #{n}"]
arr2.each {|j| puts j}
# portions of arrays can be passed around
arr3 = arr2[1,2]
arr3.each {|j| puts j}

# arrays can be extended
arr3[2] = 'hi'
arr3.each {|j| puts j}

# functions (methods)
puts "ruby functions"
def square(x) 
  return x * x
end
puts square(3)

# optional arguments
def print_error(error_message = 'Error: ', error_num = 0)
  puts "Error #{error_num}: #{error_message}" 
end
# two alternative ways to call a function:
print_error("Undefined variable", 3)
print_error "Undefined variable", 3

print_error "Undefined variable"

puts "Ruby blocks"
# blocks are segments of code
# blocks can be passed as parameters to methods
def thecall 
  yield # excutes the block
end
thecall {puts "my block"}

# blocks with parameters
def call_parameter
  yield(5)
  yield('Hi')
end
call_parameter {|x| puts "I am printing #{x}"}
# if more than one statement in a block, use do/end
call_parameter do |x| puts "x = "; puts x end

# blocks can return values
def call_block
  puts yield(5)
  puts yield(8.8)
end
call_block {|x| x + 7}

# symbols
puts "each object has its own id"
puts 'Hi'.object_id
puts 'Hi'.object_id
puts 'Hi'.equal?('Hi')
# symbols are small constant objects that consist only of a name 
puts :listEnd
list1 = [1, 2, 3, :listEnd]
list2 = [true, false, :listEnd]

# all copies of :listEnd are the same
i = 0
while list1[i] != :listEnd do
  puts list1[i] 
  i += 1 
end 

# hashes - array indexed by any type
# 'winter' is a key, 'skiing' is a value 
hash = {'winter' => 'skiing', 'spring' => 'basketball',
  'summer' => 'swimming', 'fall' => 'hiking'
}
hash.each_value {|value| puts value}
hash.each_key {|key| puts key}
hash.each {|key, value| puts "#{value} is a #{key} sport"}

# it is common to use symbols as keys
hash = {:winter => 'skiing', :spring => 'basketball',
  :summer => 'swimming', :fall => 'hiking'
}
hash.each_value {|value| puts value}
hash.each_key {|key| puts key}
hash.each {|key, value| puts "#{value} is a #{key} sport"}

# using lambda:
# creating a function that you can pass to another function
add_two = lambda {|x| x + 2}
puts add_two.call(5)

repeat = lambda {|y, z| y.call(y.call(z))}

# functions can now be passed around 
# cannot do it with blocks :-(
def call_two_functions(f1, f2) 
 f2.call(f1, 5)
end

puts call_two_functions(add_two, repeat)

The output


Hello World
"Hello World"
String
Fixnum
Float
0
Bignum
Fixnum
Class
Object
5
Hi there
false
FalseClass
57

NilClass
57 little monkeys jumping on the bed
#{n} little monkeys jumping on the bed
57 is not my favorite number
n = 5
5 != 55
n = 5
10 is a small number
10
5
2
1
my random number 2
the sum is 2
my random number 8
the sum is 10
my random number 7
the sum is 17
my random number 2
the sum is 19
my random number 0
the sum is 19
my random number 1
the sum is 20
Hello! 
Hello! 
Hello! 
a loop with a variable
0
1
2
3
4
a step loop
1
3
5
7
9
ranges...
5
false
true
false
true
9
0
a for loop with a range
0
1
2
3
4
5
6
7
8
9
a better loop for a range
0
1
2
3
4
5
6
7
8
9
7
traversing arrays with a loop
3
4
5
7
2
3.5
yes
n = 0
3.5
yes
3.5
yes
hi
ruby functions
9
Error 3: Undefined variable
Error 3: Undefined variable
Error 0: Undefined variable
Ruby blocks
my block
I am printing 5
I am printing Hi
x = 
5
x = 
Hi
12
15.8
each object has its own id
80260060
80260040
false
listEnd
1
2
3
skiing
basketball
swimming
hiking
winter
spring
summer
fall
skiing is a winter sport
basketball is a spring sport
swimming is a summer sport
hiking is a fall sport
skiing
basketball
swimming
hiking
winter
spring
summer
fall
skiing is a winter sport
basketball is a spring sport
swimming is a summer sport
hiking is a fall sport
7
9

UMM CSci 4657