2013-10-14 4 views
0

Возможно ли обезглавить метод с ударом в конце?Monkey-patching ruby ​​method with bang

Я хочу, чтобы обезьяна-патч String.upcase!, но я не знаю, как этого достичь.

Проблема в том, что я хочу изменить исходный объект строки.

Вот пример:

class String 
    def upcase! 
    self.mb_chars.upcase.to_s 
    end 
end 

Теперь, если я печатаю, что в консоли и попробовать его, он не работает:

[1] pry(main)> asd="asd" 
=> "asd" 
[2] pry(main)> asd.upcase 
=> "ASD" 
[3] pry(main)> asd 
=> "asd" 
[4] pry(main)> asd.upcase! 
=> "ASD" 
[5] pry(main)> asd 
=> "asd" 
+2

Это не отличается от метода без помех в конце –

+2

Предостережение: это * ваша ответственность за изменение метода вызывающего, если это то, что вы намереваетесь. Но это ничем не отличается от того, что вы несете ответственность за * не * изменение вызывающего абонента, когда вы обезьяны патчем тот же метод без взрыва. –

ответ

2

Ваша проблема не зависит от метода, имеющего удар. Если вы хотите заменить строку приемника, используйте метод String#replace.

class String 
    def foo 
    replace(whatever_string_you_want_to_replace_the_receiver_with) 
    end 
end 

Вы можете возможно поместить mb_chars.upcase в качестве аргумента replace.

+0

Спасибо, мужик! Вот так! –

0

Как насчет:

class String 
    def upcase! 
    #Your logic here 
    end 
end 
+0

Мне нужно заменить оригинальную строку. Я знаю, что могу написать то, что вы написали, но можете ли вы показать мне пример, который заменит исходную строку? –

+0

Извините, я не совсем понял, в чем проблема, с которой вы пытаетесь справиться. Пожалуйста, уточните вопрос с более подробной информацией. –

+0

Извините, мой плохой. Я просто обновил вопрос. –

6

Вам следует избегать обезглавливания верхнего уровня класса, такого как String. Если вы хотите знать, почему, я настоятельно рекомендую вам прочитать Monkeypatching is Destroying Ruby by Avdi Grimm.

Теперь, чтобы ответить на ваш вопрос, вы могли бы сделать что-то вроде этого:

class String 
    def upcase! 
    replace(upcase) # self is not mandatory here 
    end 
end 

> s = "foo" 
=> "foo" 
> s.upcase 
=> "FOO" 
> s 
=> "foo" 
> s.upcase! 
=> "FOO" 
> s 
=> "FOO" 
1

Челка просто часть имени метода. Это абсолютно не имеет никакого значения. Вы пишете метод с ударом в конце точно так же, как вы пишете метод с «o» или «z» в конце.