你的代码应该是:
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(' ') 给出了["what", "is", "the", "dog"],并且您正在将这个 array 对象推送到数组 string。因此string 变成了[["what", "is", "the", "dog"]]。因此string 是一个大小为1 的数组。因此,如果您想访问任何索引,例如1、2 等等,您将获得nil。您可以使用p(它在阵列上调用#inspect)来调试它,但不能使用puts。
def morse_code(str)
string = []
string.push(str.split(' '))
p string
end
morse_code("what is the dog" )
# >> [["what", "is", "the", "dog"]]
对于Array,puts 的工作方式与p 完全不同。我总是不擅长阅读 MRI 代码,因此我有时会看一下 Rubinious 代码。看看他们是如何定义IO::puts 的,它与MRI 相同。现在看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
我们现在可以确定,IO::puts 或 Kernel::puts 与 array 的行为方式完全相同,就像 Rubinious 人实现的那样。您现在也可以查看 MRI 代码。我刚刚找到了一个MRI,看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