Как разделить код между уточнениями ruby?
module Ext
refine Hash do
def foo
puts :in_foo
end
def bar
puts :in_bar
foo
end
end
end
module Test
using Ext
Hash.new.bar
end
# in_bar
# in_foo
# => nil
Это работает как ожидалось. Но если я хочу поделиться foo
а также bar
между Hash
а также Array
используя include
, это не удается.
module Shared
def foo
puts :in_foo
end
def bar
puts :in_bar
foo
end
end
module Ext
refine Hash do
include Shared
end
refine Array do
include Shared
end
end
module Test
using Ext
Hash.new.bar
end
# in_bar
# NameError: undefined local variable or method `foo' for {}:Hash
Есть ли способ поделиться кодом между уточнениями?
1 ответ
Проблема не в том, чтобы делиться. Избавляться от Array
уточнение полностью, и вы получите то же самое поведение.
Согласно документации:
Уточнения активны до конца файла или до конца строки eval, соответственно. Уточнения носят лексический характер. Когда контроль переносится за пределы области, уточнение деактивируется. Это означает, что если вам требуется или загрузить файл или вызвать метод, который определен вне текущей области, уточнение будет деактивировано.
Тем не менее, то, что не удается в ваших примерах refine do ⇒ include
, Язык не готов к пониманию include
внутри refine
пункт. Возможно, это будет возможно в будущем, когда функция выйдет из "экспериментальной" стадии.
Если вы все еще думаете, что хотите полагаться на доработки, вы можете обмануть ruby (глобальные значения для ясности идеи):
$ref = lambda do
def foo
puts :in_foo
end
public :foo
def bar
puts :in_bar
foo
end
public :bar
end
module Ext
refine ::Hash do
$ref.call
end
end
module Test
using Ext
::Hash.new.bar
end
#⇒ in_bar
#⇒ in_foo