Вы можете добавить метод экземпляра, но вы будете нуждаться, чтобы прыгать через обруч цепи методы:
str = 'now is the time'
def str.foo(target, replacement)
self.gsub(target, replacement)
end
def str.bar
self.reverse
end
str.singleton_methods # => [:foo, :bar]
str.foo('ow', 'ever') # => "never is the time"
str.bar # => "emit eht si won"
Это не будет работать:
str.foo('ow', 'ever').bar
# ~> NoMethodError
# ~> undefined method `bar' for "never is the time":String
Вы можете использовать методы типа «удар», которые мутируют исходный объект:
str = 'now is the time'
def str.foo(target, replacement)
self.gsub!(target, replacement)
self
end
def str.bar
self.reverse!
self
end
str.singleton_methods # => [:foo, :bar]
str.foo('ow', 'ever').bar # => "emit eht si reven"
Будьте осторожны, хотя. Это не будет работать для каждого типа объектов, только те, которые позволяют мутировать.
И тот факт, что добавленные методы доступны только этой конкретной переменной, действительно ограничивает; Это бесполезное повторное использование той же функциональности. Вы можете clone
переменную и назначить этот клон новой переменной, но заменяя значение с чем-то другом становится грязным:
str2 = str.clone
str.object_id # => 70259449706680
str2.object_id # => 70259449706520
str.singleton_methods # => [:foo]
str2.singleton_methods # => [:foo]
str2 = 'all good men'
str2.foo('ll', '') # =>
# ~> NoMethodError
# ~> undefined method `foo' for "all good men":String
Лично я хотел бы сделать это с помощью подкласса:
class MyString < String
def foo(s, t)
self.gsub(s, t)
end
end
str = MyString.new('now is the time')
str.foo('ow', 'ever') # => "never is the time"
str2 = 'all good men'
str2.foo('ll', '') # =>
# ~> NoMethodError
# ~> undefined method `foo' for "all good men":String
Если вы на Ruby v2 +, посмотрите на ответ @ mdesantis, используя уточнения. Они были введены для решения такого рода проблем. Если вы < v2.0, я бы пошел маршрут подкласса или согласился с необходимостью изменять String.
всегда может добавить к экземпляру. –
@DaveNewton Я мог бы, но это было бы дорого, потому что все эти преобразования одинаковы. –
... Затем добавьте его в строку или используйте реализацию «озабоченность», вероятно, также немного дороже. –