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 :<<.

War es hilfreich?

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top