Лучший способ организовать длинный кусок кода в блоке уточнения ruby
module Access
def last
self[-1]
end
def start_end
self[0] + last
end
end
module StringExt
refine String do
include Access
end
end
using StringExt
puts 'abcd'.last # => d
puts 'abcd'.start_end
Когда класс очищается с помощью слишком большого количества связанных методов, я думаю, что лучше извлечь их в модуль. Тем не менее, в приведенном выше примере, который демонстрирует проблему, когда один метод вызывает другой (см. Последний оператор), и он выдает следующую ошибку.
в 'start_end': неопределенная локальная переменная или метод 'last' для "abcd":String (NameError)
Подобная проблема была решена с помощью глобальной переменной, которая также работает для моего примера. Но я ищу другой лучший способ организовать уточняемые методы и избегать глобальных изменений.
Как бы посоветовать лучший способ организовать эти методы?
1 ответ
Вот общий шаблон, который я в итоге использовал. По сути, я не нашел обходного пути для использования глобальных идентификаторов на каком-то уровне. Но это может быть сделано довольно чисто, создавая эти глобальные классы / модули. Это будет более понятно в качестве примера:
module StringPatches
def self.non_empty?(string)
!string.empty?
end
def non_empty?
StringPatches.non_empty?(self)
end
def non_non_empty?
!StringPatches.non_empty?(self)
end
refine String do
include StringPatches
end
end
class Foo
using StringPatches
puts "asd".non_empty? # => true
puts "asd".non_non_empty? # => false
end
Методы класса на StringPatches
не экспортируется в using
, Но поскольку классы / модули являются константами (глобальными переменными), к ним можно получить доступ откуда угодно.