Уточнения и пространства имен

Попытка исправить net/http и применить его только к одному классу обслуживания. Уточнения, кажется, путь. Патч обезьяны ниже работает, а уточнение - нет. Это проблема пространства имен? Проект на ruby ​​2.3.0, но пробовал и с 2.4.1, и, кажется, только патч обезьяны применяется.

С патчем обезьяны:

module Net
  class HTTPGenericRequest
    def write_header(sock, ver, path)
      puts "monkey patched!"
      # patch stuff...
    end
  end
end

Service.new.make_request
# monkey patched!

С уточнением:

module NetHttpPatch
  refine Net::HTTPGenericRequest do
    def write_header(sock, ver, path)
      puts "refined!"
      # patch stuff...
    end
  end
end

class Service
  using NetHttpPatch
end

Service.new.make_request
# :(

ОБНОВИТЬ:

Кажется, это похоже на сферу? Очевидно, что более сложные вещи происходят, когда net/http делает запрос, теряет ли он тогда область?

module TimeExtension
  refine Fixnum do
    def hours
      self * 60
    end
  end
end

class Service
  using TimeExtension

  def one_hour
    puts 1.hours
  end
end

puts Service.new.one_hour
# 60

ОБНОВЛЕНИЕ ОБНОВЛЕНИЕ:

нвм, я вижу, что происходит сейчас:) должны держать ваш мозг от смешивания using с тем, как работают миксины.

module TimeExtension
  refine Fixnum do
    def hours
      self * 60
    end
  end
end

class Foo
  def one_hour
    puts 1.hours
  end
end


class Service
  using TimeExtension

  def one_hour
    puts 1.hours
  end

  def another_hour
    Foo.new.one_hour
  end
end

puts Service.new.one_hour
# 60
puts Service.new.another_hour
# undefined method `hours' for 1:Fixnum (NoMethodError)

1 ответ

Решение

Это проблема пространства имен?

Это вопрос масштаба. Уточнения имеют лексическую область:

class Service
  using NetHttpPatch
  # Refinement is in scope here
end

# different lexical scope, Refinement is not in scope here

class Service
  # another different lexical scope, Refinement is *not* in scope here!
end

Первоначально был только main::using, которая была ограничена сценарием, т.е. уточнение находилось в области действия для всей оставшейся части сценария. Module#using позже, оно охватывает уточнение в теле определения лексического класса.

Другие вопросы по тегам