Ruby Basics (Part 2)

(Following tutorial here)

Classes

Classes are capitalized (String, Integer, Float, Array, etc).

Time

There’s a Time Class. It represents moments in time, and you can add or subtract to get new times. 1.5 is a second and a half.

time = Time.new
time2 = time + 120

puts time
puts time2
2019-06-08 11:57:22 -0700
2019-06-08 11:59:22 -0700

The last segment indicates timezone (more: how to work with time zones in Ruby.)

Time.mktime makes a specific time.

puts Time.mktime(2000, 1, 1)
  # returns 2000-01-01 00:00:00 -0800

Hash

Hashes are like JavaScript Objects.

prices = {}
prices['apple'] = 1000
prices['orange'] =900

Extending Classes

class Integer
  def to_eng
    if self == 1
      english = 'one'
    else
      english = 'something else'
    end

    english
  end
end

puts 1.to_eng

It’s an incomplete implementation, but you can now call 1.to_eng to get the English phrase of the integer in the same way you call 1.to_s to convert it to a string.

self is similar to this in JavaScript (more here), and refers to the object that ‘owns’ the executing code.

Instance Variables

Instance variables are basically an object’s variables. To differentiate them from local variables, they have an “@” in front.

class Die

  def initialize
    roll
  end

  def roll
    @numberShowing = 1 + rand(6)
  end

  def showing
    @numberShowing
  end

end

Blocks and procs

Ruby has the ability to take a block of code (the code between do and end, wrap it up in an object (called ‘proc’), store it in a variable or pass it to a method.

doYouEat = Proc.new do |foodItem|
  puts "No, I don't eat #{foodItem}."
end

doYouEat.call 'cigarettes'
doYouEat.call 'people'

Why not just use methods?

Because you can’t do some things with methods, like passing methods into other methods, or return methods.

Procs (procedures) are objects, and therefore can be passed into or returned from methods.

Methods taking Procs

def doSelfImportantly someProc
  puts 'Everybody HOLD ON! I have something to do...'
  someProc.call
  puts 'Ok I'm done.'
end

sayHello = Proc.new.do
  puts 'hello'
end

sayGoodbye = Proc.new.do
  puts 'goodbye'
end

doSelfImportantly sayHello
doSelfImportantly sayGoodbye

Methods returning Procs

def compose proc1, proc2
  Proc.new do |x|
    proc2.call(proc1.call(x))
  end
end

squareIt = Proc.new do |x|
  x * x
end

doubleIt = Proc.new do |x|
  x + x
end

doubleThenSquare = compose doubleIt, squareIt
squareThenDouble = compose squareIt, doubleIt

puts doubleThenSquare.call(5)
puts squareThenDouble.call(5)

Passing blocks into methods

class Array
  def eachEven(&wasABlock_nowAProc)
    # We start with "true" because arrays start with 0, which is even.
    isEven = true

    self.each do |object|
      if isEven
        wasABlock_nowAProc.call object
      end

      isEven = (not isEven)  # Toggle from even to odd, or odd to even.
    end
  end
end

['apple', 'bad apple', 'cherry', 'durian'].eachEven do |fruit|
  puts 'Yum!  I just love '+fruit+' pies, don\'t you?'
end

# Remember, we are getting the even-numbered elements
# of the array, all of which happen to be odd numbers,
# just because I like to cause problems like that.
[1, 2, 3, 4, 5].eachEven do |oddBall|
  puts oddBall.to_s+' is NOT an even number!'
end

To pass in a block to eachEven, we just need to stick the block after the method. In order for the method to not ignore the block but turn it into a proc, put the name of the proc at the end of the method’s params list, preceded by an ‘&’.

Leave a comment

Design a site like this with WordPress.com
Get started