3

I don't understand how this isn't working. The program is supposed to take instance method second in the class Array and return the 2nd object in the array

class Array
  def second(*arr)
  arr.length <= 1 ? nil : arr[1]
  end
end

#Test cases
Test.assert_equals(Array([1, 2, 3]), 2,) #Getting nil
Test.assert_equals(Array([]), nil) #passes
Test.assert_equals(Array([1]), nil) #passes

What am I doing wrong? if I remove class Array and test on second it works fine?

user3466773
  • 176
  • 1
  • 2
  • 14

2 Answers2

5

Why use *arr? If you're monkey-patching Array, then use self:

class Array
  def second
    self.length <= 1 ? nil : self[1]
  end
end

p [1,2,3].second #=> 2
p [1].second #=> nil
p [].second #=> nil 
daremkd
  • 8,244
  • 6
  • 40
  • 66
  • That worked. I didn't really know what self was. I'm pretty new to Ruby and brand new to Ruby's class notation haha Thanks – user3466773 Nov 12 '14 at 01:43
  • You're welcome, I've seen you ask several questions here, and if you find a particular answer useful, it's a good practice to accept it by clicking on the check box on the left. – daremkd Nov 12 '14 at 01:46
1

In answer to what you're doing wrong, your code as written doesn't need the splat (*) operator (it also doesn't need to be patched into the Array class). While patching into Array and using self allows you to call it like [1,2].second, you could also write it as follows without patching into Array:

def second(arr)
  arr.length <= 1 ? nil : arr[1]
end

Which would need to be called like second([1,2]).

To find out more about the splat operator *, try something like this explanation (I confess - the first Google result, but seems ok), but what it's doing in your example is turning your passed-in array into an array of an array - e.g. [1,2,3] becomes [[1,2,3]].

Kimball
  • 1,241
  • 11
  • 17