Question

Ce qui m'intéresse, c'est de savoir comment cela fonctionnerait:

me = "this is a string"
class << me
  alias :old<< :<<
  def <<(text)
    old<<(text)
    puts "appended #{text}"
  end
end

J'aimerais que lorsque quelque chose soit ajouté à la variable me, l'objet utilise la méthode redéfinie.

Si j'essaie de l'exécuter, je reçois syntax error, unexpected ':', expecting kEND à :<<.

Était-ce utile?

La solution

:old<< ressemble à & "; :old << &". Essayez simplement :"old<<", ou si vous le souhaitez vraiment, <=> (mais amusez-vous à l'appeler par ce nom).

Autres conseils

Seuls certains caractères sont autorisés dans les littéraux de symboles. Vous recherchez:

alias :"old<<" :"<<"

Comme d'autres l'ont déjà expliqué, le problème est simplement que old<< n'est pas un identifiant Ruby légal. Vous pouvez, avec des astuces, créer une méthode portant ce nom, mais vous ne pouvez pas l'appeler de manière habituelle, et elle ne sera certainement pas reconnue en tant qu'opérateur.

Cependant, jusqu’à présent, toutes les réponses, bien qu’ils aient certainement répondu à votre question, ont complètement ignoré le problème sous-jacent : cette méthode ne devrait même pas avoir de nom! Et s'il n'a pas de nom, le problème de son illégalité ne se pose tout simplement pas.

#!/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

Dans ce cas, la méthode n'est jamais nommée, ce qui signifie non seulement que nous n'avons pas à inventer de nom, mais également qu'elle ne pollue pas l'espace de nom.

Le problème vient de :old<<. Il est interprété comme :old <<, c’est-à-dire un symbole :old suivi de l’opérateur <<. Il s’agit donc d’une erreur de syntaxe. Peut-être que vous pouvez essayer :"old<<"?

Bien que je sois d’accord avec thenduks et ephemient, vous pouvez aliaser l’opérateur de cette façon puis utiliser send pour l’appeler, mais vous pouvez également utiliser l’héritage de classe. par exemple:

me = "is a string"

class << me
  def <<(text)
    super
    puts "appended #{text}"
  end
end

me << " bob"
puts me #=> is a string appended bob
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top