Почему открытие класса String внутри файла не работает?
Я знаю, что могу открыть класс как String
и добавить функциональность. Этот тестовый скрипт camelize.rb
работает довольно хорошо
#!/usr/bin/env ruby
class String
def camelize
self.split("_").map(&:capitalize).join
end
end
class Test
def test
p "test_me".camelize
end
end
Test.test
Печать "TestMe"
Однако внутри файла тор это не работает. Например test.thor
p "TEST ONE"
class String
p "TEST TWO"
def camelize
self.split("_").map(&:capitalize).join
end
end
class Test < Thor
p "TEST THREE"
desc "camel", "A test"
def camel
p "test_me".camelize
end
end
Установка через thor install test.thor
, Бег
$ thor test:camel
"TEST ONE"
"TEST TWO"
"TEST THREE"
/Users/Kassi/.thor/ba3ea78d7f807c4c13ec6b61286788b5:13:in `camel': undefined method `camelize' for "test_me":String (NoMethodError)
Почему и как это исправить?
1 ответ
Зачем?
Проблема здесь:
Thor::Sandbox.class_eval(content, path)
Таким образом, он берет ваш файл и загружает его в пустой модуль, таким образом, помещая его в пространство имен (не уверен, что квалифицируется как "песочница").
class Thor
module Sandbox
end
end
Итак, ваша попытка открыть String
на самом деле создает новый класс Thor::Sandbox::String
о котором никто не знает. Строковые литералы продолжают создавать экземпляры String
,
Как исправить?
Откройте строку верхнего уровня вместо создания вложенной.
class ::String
def camelize
self.split("_").map(&:capitalize).join
end
end
Бонусный контент
Тор на самом деле уже включает в себя метод верблюжьей струны, Thor::Util.camel_case
:
def camel_case(str)
return str if str !~ /_/ && str =~ /[A-Z]+.*/
str.split("_").map { |i| i.capitalize }.join
end