Your code should be :
def morse_code(str)
string = []
string.push(*str.split(' '))
puts string
p string[2]
end
morse_code("what is the dog" )
# >> what
# >> is
# >> the
# >> dog
# >> "the"
str.split(' ') is giving ["what", "is", "the", "dog"], and you are pushing this array object to the array string. Thus string became [["what", "is", "the", "dog"]]. Thus string is an array of size 1. Thus if you want to access any index like 1, 2 so on.., you will get nil. You can debug it using p(it calls #inspect on the array), BUT NOT puts.
def morse_code(str)
string = []
string.push(str.split(' '))
p string
end
morse_code("what is the dog" )
# >> [["what", "is", "the", "dog"]]
With Array, puts works completely different way than p. I am not good to read MRI code always, thus I take a look at sometime Rubinious code. Look how they defined IO::puts, which is same as MRI. Now look the specs for the code
it "flattens a nested array before writing it" do
@io.should_receive(:write).with("1")
@io.should_receive(:write).with("2")
@io.should_receive(:write).with("3")
@io.should_receive(:write).with("\n").exactly(3).times
@io.puts([1, 2, [3]]).should == nil
end
it "writes nothing for an empty array" do
x = []
@io.should_receive(:write).exactly(0).times
@io.puts(x).should == nil
end
it "writes [...] for a recursive array arg" do
x = []
x << 2 << x
@io.should_receive(:write).with("2")
@io.should_receive(:write).with("[...]")
@io.should_receive(:write).with("\n").exactly(2).times
@io.puts(x).should == nil
end
We can now be sure that, IO::puts or Kernel::puts behaves with array just the way, as Rubinious people implemented it. You can now take a look at the MRI code also. I just found the MRI one, look the below test
def test_puts_recursive_array
a = ["foo"]
a << a
pipe(proc do |w|
w.puts a
w.close
end, proc do |r|
assert_equal("foo\n[...]\n", r.read)
end)
end