Ruby gsub не меняет содержимое, а настройка содержимого - PullRequest
5 голосов
/ 30 марта 2012

Может кто-нибудь объяснить, пожалуйста, разницу между следующими двумя строками кода:

1. element.content.gsub!("#{i}", "#{a[i]}")
2. element.content = element.content.gsub("#{i}", "#{a[i]}")

В следующем коде:

a.each_index do |i|
  @doc.traverse do |element|
    if element.text?
      element.content = element.content.gsub("#{i}", "#{a[i]}")
    end
  end
end
puts @doc

Код, представленный выше, действительно меняет @doc. Хотя, если я использую строку 1 с gsub!, это не повлияет на @doc. Связано ли это с тем, как блоки обрабатывают свои параметры? Разве все не должно передаваться по ссылке в Ruby, если оно явно не скопировано с помощью метода?

1 Ответ

4 голосов
/ 30 марта 2012

Проверка http://nokogiri.org/Nokogiri/XML/Node.html:

static VALUE get_content(VALUE self) {
    xmlNodePtr node;
    xmlChar * content;
    Data_Get_Struct(self, xmlNode, node);
    content = xmlNodeGetContent(node);
    if(content) {
        VALUE rval = NOKOGIRI_STR_NEW2(content);
        xmlFree(content);
        return rval;
    }
    return Qnil;
}

Копирование содержимого выполняется, поэтому любые изменения в нем влияют только на эту копию, а не на внутреннее значение содержимого узла.

Использование element.content = вызывает отдельный метод, который изменяет внутреннее значение:

def content= string
    self.native_content = encode_special_chars(string.to_s)
end
...