Können Ruby -Operatoren aliased sein?
-
05-07-2019 - |
Frage
Ich bin daran interessiert, wie man dies zum Laufen bringen würde:
me = "this is a string"
class << me
alias :old<< :<<
def <<(text)
old<<(text)
puts "appended #{text}"
end
end
Ich würde es mögen, wenn etwas an die angehängt wird me
Variable verwendet das Objekt die neu definierte Methode.
Wenn ich versuche, das auszuführen, bekomme ich syntax error, unexpected ':', expecting kEND
bei :<<
.
Lösung
:old<<
sieht aus wie ":old
<<
". Versuchen Sie es einfach :old
, oder wenn Sie wirklich wollen, :"old<<"
(Aber haben Sie Spaß, es durch diesen Namen zu rufen).
Andere Tipps
In Symbol -Literalen sind nur bestimmte Zeichen erlaubt. Du suchst nach:
alias :"old<<" :"<<"
Wie andere bereits erklärt haben, ist das Problem einfach das old<<
ist keine legale Rubinkennung. Sie können mit Tricks eine Methode mit diesem Namen erstellen, aber Sie können sie nicht auf normale Weise anrufen, und sie wird sicherlich nicht als Operator erkannt.
Alle bisherigen Antworten haben jedoch die Frage, obwohl sie Ihre Frage sicherlich beantwortet haben zugrundeliegend Problem: Diese Methode sollte überhaupt nicht einmal einen Namen haben! Und wenn es keinen Namen hat, tritt das Problem, dass der Name illegal ist, einfach nicht einmal auf.
#!/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
In diesem Fall wird die Methode nie benannt, was nicht nur bedeutet, dass wir keinen Namen dafür erfinden müssen, sondern auch, dass sie den Namespace nicht verschmutzt.
Das Problem ist mit :old<<
. Es wird als interpretiert als :old <<
, dh ein Symbol :old
gefolgt von der <<
Operator, es ist also ein Syntaxfehler. Vielleicht kannst du es versuchen :"old<<"
?
Obwohl ich mit diesen und kurzfristig einverstanden bin, können Sie den Bediener auf diese Weise verweigern und dann senden, um es anzurufen. z.B:
me = "is a string"
class << me
def <<(text)
super
puts "appended #{text}"
end
end
me << " bob"
puts me #=> is a string appended bob