views:

76

answers:

1

I have some methods for a class which return arrays like ["1", "3", "2", "6", "2"]. It is ok that these are string arrays, not numeric. I have another method that takes an array, and turns it into a single string like this 1 3 2 6 2.

class Turn
def initialize
    @rolls = 1
    @dice = []
end
def roll
    @roll = []
    x = 5 - @dice.length
    x.times do |i|
        @roll[i] = rand(6) + 1
    end
    @roll  # ["1", "3", "2", "6", "2"]
end
def show
    @dice  # ["1", "3", "6"]
end
def line(something)
    temp = ""
    something.each do |x|
        temp << x + " "
    end
    puts temp   # "1 3 6 " or "1 3 2 6 2 "
end
end

Then I want to be able to chain methods together so I could do

first = Turn.new
first.roll.line
first.show.line

However, I really don't know how to do this, and I haven't been able to find how online. I have seen self get returned, but I can't really figure out what it does. The code in the line method works if I move it into another method, so the problem is really just dealing with the chaining and returning.

If someone could not only help with code, but with how chaining works with regards to return values and how returning self works, that would be awesome.

Thank you!

+1  A: 

Since your #roll and #show methods return an array, you'd need to define a method Array#line to actually be able to do first.roll.line.

Btw, there's already Array#join which also joins array elements together to a string, just like your #line method, so you could as well use first.roll.join(' ') and get rid of your #line method.

Andreas
Your second part is perfect! Thank you for explaining the first part as well. So as I read from left to right, each method returns a value, which is acted upon by the next method?
phoffer
yes, each method will return the last argument. a great way to see this is to use the irb console.
Jed Schneider
@Jed Are you referring to the fact that the last argument in a method is returned, so you don't need to explicitly have `return @dice`? Because I already understand that. I am wondering about when you have multiple methods chained together, how they pass the returned values around.
phoffer
You can think of `first.roll.join(' ')` being the same as `tmp = first.roll` followed by `tmp.join(' ')`. first is a variable containing an object (an instance of class Turn). first.roll calls the method #roll on that object, which returns an array (an object that is an instance of class Array). On this array, you call the method #join, which returns a string (an instance of class String). So yes, if you chain method calls like this, every "step" calls an instance method on the returned thing of the previous "step".
Andreas
@Andreas Thanks Andreas, that is what I was wondering. I've added some more complicated chaining like that, and everything is working great.
phoffer
does this clear it up? http://codepad.org/2ocKVMd6
Jed Schneider