0

这让我很困惑:

class Person 
    attr_accessor :id, :name

    def initialize(init)
        init.each_pair do |key, val|
            instance_variable_set('@' + key.to_s, val)
        end
    end
end

@adam = Person.new(:id => 1, :name => "Adam")
@eve = Person.new(:id => 2)

@people = [ @adam, @eve, nil ]

print @people

@people.map! do |person|
    person ||= Person.new(:id => 3, :name => "Some default")

    if person.name.nil?
        person.name = "Eve"
    end
end 

print @people 

# outputs 
# [#<Person:0x007ff184303900 @id=1, @name="Adam">, #<Person:0x007ff184303770 @id=2>, nil]
# [nil, "Some default", "Some default"]

我想完全填充@people,以便最终得到以下内容:

[#<Person:0x007ff184303900 @id=1, @name="Adam">, #<Person:0x007ff184303770 @id=2,  @name="Eve">, #<Person:0x007ff184301111 @id=3,  @name="Some default">]

我究竟做错了什么?

4

2 回答 2

2

它的作用是调用您map提供的块,将集合的元素传递给它并获取从块返回的值。在没有显式return关键字的情况下,块的值是最后评估的表达式的值。那将是if您示例中的表达式。它可以返回其中一个nil或一个名称。这些值被映射到原始集合。修复很简单:只需确保Person从块中返回 a (例如,通过最后评估它)。

@people.map! do |person|
  person ||= Person.new(:id => 3)

  if person.name.nil?
    person.name = "Some default"
  end
  person
end

print @people

# >> [#<Person:0x007fb5f288b288 @id=1, @name="Adam">, #<Person:0x007fb5f288b0f8 @id=2, @name="Some default">, #<Person:0x007fb5f288ae28 @id=3, @name="Some default">]
于 2013-05-29T15:37:13.980 回答
1

。地图!用 .map 的返回值替换每个元素!方法(在这种情况下是 person.name)。在您的.map 末尾添加一个“返回人”!方法。或者做一个 .each 而不是 .map

于 2013-05-29T15:37:02.073 回答