Открытые занятия в модуле
Я знаю, что могу выполнить следующее, чтобы добавить методы в класс String
class String
def do_something
puts self.size
end
end
var = "test"
var.do_something
и это вернется 4
Я хочу иметь возможность иметь модуль с функцией, которая принимает строку, но иметь возможность вызывать do_something
метод для этой строки (см. ниже, например) - возможно ли это?
РЕДАКТИРОВАТЬ: Добавлен пример кода, который не работает
module TestModule
class String
def do_something
puts self.size
end
end
def self.test(str)
str.do_something
end
end
Это дает ошибку: undefined method 'do_something' for "hello":String (NoMethodError)
2 ответа
Как написан ваш код, вы определяете новый класс с именем TestModule::String. Если вы хотите изменить встроенный класс Ruby String, вам нужно использовать полное имя String (с ""::"), если вы хотите сохранить объявление внутри модуля.
module TestModule
class ::String
def do_something
puts self.size
end
end
def self.test(str)
str.do_something
end
end
Добавление "::" говорит Ruby, что нужный вам класс String не является частью TestModule.
Вероятно, будет проще объявить String вне TestModule в том же файле.
Если вы не хотите загрязнять глобальный класс String, вы можете просто изменить конкретный экземпляр String, к которому вы хотите добавить метод.
module TestModule
def self.test(str)
do_somethingify!(str)
str.do_something
end
def self.do_somethingify!(str)
unless str.respond_to? :do_something
str.instance_eval do
def do_something
puts size
end
end
end
end
end
Может быть, это?
module TestModule
module_function
def test(str)
str.instance_eval{doSomething}
end
end
Test.test(str)
Изменить Изменено из-за изменения в вопросе
Просто поместите определение doSomething
снаружи TestModule
учебный класс.
class String
def doSomething
puts size
end
end
module TestModule
module_function
def test(str)
str.doSomething
end
end