Skip to content

Instantly share code, notes, and snippets.

@horshacktest
Last active August 15, 2016 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save horshacktest/22ce166166948494599847e7f4031bc6 to your computer and use it in GitHub Desktop.
Save horshacktest/22ce166166948494599847e7f4031bc6 to your computer and use it in GitHub Desktop.
notes on a ruby code example

I'm learning the basics of ruby and found a site with some interesting articles. I'm reading one about using mixins and how they can be used to easily add a bunch of useful functions to your class.

Here is some example code that confused me.

class Queue 
  include Enumerable

  def initialize(file)
    @file = file
  end

  def entries
    return [] if empty?

    File.read(@file).split("\n").map { |e| e.to_f }
  end

  def each
    entries.each { |e| yield(e) }
  end

  # additional unrelated methods omitted
end

This mostly makes sense to me. It has an initializer that takes a filename, then if the object is queried for its contents using the entries method it reads the file, turns each line into an array item and returns the array. Unless something is empty, then it returns an empty array.

What is this invisible "something" that might be empty? If I was writing a class like this I would expect to need an instance variable (say, the_data) to hold the object's data. And I would write that line return [] if @the_data.empty? I does not seem like the line as-is should work. I tested it out in repl.it I made a new Queue object and tried to call #entries on it. Sure enough it blew up. empty? not initialized

empty? is a method right? Should I be picking it up from Enumerable?

Nope. empty? is not defined in Enummerable

If I simply comment out return [] if empty? the class works and I can play around with it.

see: https://repl.it/CmIk/21

q = Queue.new("vals.txt")
q.entries # no bomb!
puts q.entries.length
puts q.entries.class
q.entries.each { |i| puts i.object_id }

outputs:

4
Array
214906144718585858
200550920906342402
258464397364559874
301459700057112578

That was fun, but I'm still lost about how that empty? line is supposed to function.

It's starting to feel like Queue is working like a wrapper around some generic Enumerable-ish type. I look up the entries method to see if it's in Enummerable and to see if there is anything special about it. Yes, Enummerable does have an entries method.

So maybe #entries works as an accessor to some hidden instance data managed by Enumerable?

I then implememnted #empty? directly in the Queue class https://repl.it/CmIk/22 to return false all the time. I uncommented return [] if empty? and ran the code. It still worked as I expected. That was pretty much a time-waster while I hoped for another idea...

The fact that the sample code seems to pull the #empty? method out of thin air, implied that it belongs to some other ruby class.

Aha. It's an Array method It "Returns true if self contains no elements."

self contains no elements.

It feels like if you're inside Queue and calling #empty? on its own, with the implied reciever (<- correct word???) being self (an instance of Queue in this case?), then Queue needs to be a subclass of Array.

class Queue < Array

Let's try thatand run it. see: https://repl.it/CmIk/23

Oh dear.

main.rb:1:in `<main>': superclass mismatch for class Queue (TypeError)

Superclass mismatch what? I thought my Queue was a plain old ruby object.

Apparently not. Queue

Maybe Queue() didn't exist as a core object when this this example was written (November 2010)

Yes it did.

This is starting to look like a bad bit of sample code. I almost got it working by changing the name of the class to QueueThingy and setting a default value in the array so it's not failing the empty? test before it can read the file. But now it's a type that is an array that also has entries. see: https://repl.it/CmIk/24

I'm still confused why the entries method has the line testing for no entries before the line that reads its entries from the file. Maybe they did mean to use the core Queue class but there is no mention of threads in the example. That's what the Queue class is for right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment