Уточнения и пространства имен
Попытка исправить 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
позже, оно охватывает уточнение в теле определения лексического класса.