1

これを機能させる方法に興味があります:

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

me変数に何かが追加されたときに、オブジェクトが再定義されたメソッドを使用するようにしたいと思います。

これを実行しようとすると、になりsyntax error, unexpected ':', expecting kENDます:<<

4

5 に答える 5

7

シンボルリテラルでは、特定の文字のみが許可されます。あなたは探している:

alias :"old<<" :"<<"
于 2009-10-22T18:27:11.403 に答える
3

:old<<「」のように見えます:old <<。試してみてください:old、または本当に必要な場合は:"old<<"(ただし、その名前で呼び出すのを楽しんでください)。

于 2009-10-22T18:26:08.753 に答える
2

他の人がすでに説明しているように、問題は単純にそれ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

この場合、メソッドに名前が付けられることはありません。これは、メソッドの名前を発明する必要がないことを意味するだけでなく、名前空間を汚染しないことも意味します。

于 2009-10-23T23:18:55.053 に答える
1

問題はにあり:old<<ます。:old <<これは、つまり、記号:oldの後に<<演算子が続くものとして解釈されるため、構文エラーです。多分あなたは試すことができ:"old<<"ますか?

于 2009-10-22T18:26:59.157 に答える
0

私はthenduksとephemientに同意しますが、そのように演算子をエイリアスしてからsendを使用して呼び出すことができますが、クラス継承も使用できます。例えば:

me = "is a string"

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

me << " bob"
puts me #=> is a string appended bob
于 2010-07-01T07:51:25.620 に答える