我对如何让它发挥作用很感兴趣:
me = "this is a string"
class << me
alias :old<< :<<
def <<(text)
old<<(text)
puts "appended #{text}"
end
end
我希望当某些东西被附加到me
变量时,该对象将使用重新定义的方法。
如果我尝试运行它,我会得到syntax error, unexpected ':', expecting kEND
.:<<
我对如何让它发挥作用很感兴趣:
me = "this is a string"
class << me
alias :old<< :<<
def <<(text)
old<<(text)
puts "appended #{text}"
end
end
我希望当某些东西被附加到me
变量时,该对象将使用重新定义的方法。
如果我尝试运行它,我会得到syntax error, unexpected ':', expecting kEND
.:<<
符号文字中只允许使用某些字符。您正在寻找:
alias :"old<<" :"<<"
:old<<
看起来像“ :old
<<
”。试试:old
,或者如果你真的想要,:"old<<"
(但通过这个名字来称呼它很有趣)。
正如其他人已经解释的那样,问题只是这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
在这种情况下,该方法永远不会被命名,这不仅意味着我们不必为它发明名称,还意味着它不会污染命名空间。
问题出在:old<<
. 它被解释为:old <<
,即运算符:old
后跟的符号<<
,因此是语法错误。也许你可以试试:"old<<"
?
虽然我同意 thenduks 和 ehemient,但您可以以这种方式为运算符起别名,然后使用 send 来调用它,您仍然可以使用类继承。例如:
me = "is a string"
class << me
def <<(text)
super
puts "appended #{text}"
end
end
me << " bob"
puts me #=> is a string appended bob