Как уже объяснили другие, проблема в том, что old<<
не является допустимым идентификатором Ruby. С помощью трюков вы можете создать метод с таким именем, но вы не можете вызывать его обычными способами, и он, безусловно, не будет распознаваться как оператор.
Тем не менее, все ответы, хотя они наверняка ответили на ваш вопрос, полностью проигнорировали лежащую в основе проблему : у этого метода даже не должно быть имени! И если у него нет имени, то проблема его незаконности просто не возникает.
#!/usr/bin/env ruby
require 'test/unit'
require 'stringio'
class TestOperatorDecorator < Test::Unit::TestCase
def setup; @old_stdout, $> = $>, (@fake_stdout = StringIO.new) end
def teardown; $> = @old_stdout end
def test_that_me_dot_append_writes_to_stdio
me = 'this is a string'
class << me
old_method = instance_method :<<
define_method :<< do |text|
old_method.bind(self).(text)
puts "appended #{text}"
end
end
me << 'Test'
assert_equal "appended Test\n", @fake_stdout.string
end
end
В этом случае метод никогда не получает имя, что означает не только то, что нам не нужно придумывать имя для него, но и то, что он не загрязняет пространство имен.