класс << self, alias_method и исправление обезьяны механизируют::Cookie

#ruby #mechanize #monkeypatching #alias-method #alias-method-chain

#рубиновый #механизировать #исправление обезьяны #псевдоним-метод #цепочка псевдонимов-методов

Вопрос:

У меня проблема с неправильным поведением Mechanize::Cookie, и я хочу попытаться исправить это. Мой код:

 class Mechanize::Cookie
  class << self; alias_method :old_parse, :parse end
  def self.parse(uri, str, log = Mechanize.log)
    puts 'new parse!'
    #str.gsub!(/domain[^;]*;/,'')
    old_parse(uri, str, log)
  end
end
 

когда я добавляю это, файлы cookie не добавляются, и я не могу понять почему.

Редактировать: Чтобы увидеть проблему, попробуйте этот код с исправлением monkey и без него:

 agent = Mechanize.new
agent.get 'http://www.google.com/'
pp agent.cookie_jar
 

Без заплатки вы увидите полную банку печенья, а вместе с ней пустую.

Комментарии:

1. Выводится ли «новый синтаксический анализ!»?

2. Да, «новый синтаксический анализ!» распечатывается, и я могу сказать, что old_parse тоже вызывается, потому что я поместил туда строку «puts», чтобы проверить это. Но файлы cookie не сохраняются, когда я включаю этот код.

3. И файлы cookie были сохранены, когда вы не включили код, верно?

4. @Эндрю, это верно. Я отредактировал свой вопрос, чтобы помочь показать проблему.

Ответ №1:

Похоже, что в исходном методе синтаксического анализа есть yield cookie if block_given? оператор. Вам также нужно будет иметь возможность передавать блок.

Редактировать:

Чтобы быть более понятным…

 class Foo
    def self.x
        yield "yielded from x!" if block_given?
    end
end

class Foo
    class <<self
        alias :y :x
    end
    # new implementation of x's last parameter is an optional block
    def self.x(amp;block) 
        puts "in redefined x."
        puts "block=#{block}"
        self.y(amp;block) #use the block as the last parameter 
    end
end

Foo.x{|value| puts "value is '#{value}'"}
 

Комментарии:

1. Спасибо z5h, я думаю, что это правильный ответ. Я мог бы использовать еще один совет, если он у вас есть.