2

Rubyでは、次のようなことを行う方法はありますか

class Foo
    attr_reader :var_name :reader_name #This won't work, of course
    def initialize
        @var_name = 0
    end
end

# stuff here ....

def my_method
    foo = Foo.new
    assert_equal 0,foo.reader_name
end

つまり、変数とは異なる名前を使用する変数のアクセサ メソッドを作成する標準的な方法はありますか。(もちろん、手作業でコーディングする以外に。)

4

3 に答える 3

4

使用できますalias_method

class Foo
  attr_reader :var_name
  alias_method :reader_name, :var_name
  def initialize
    @var_name = 0
  end
end

ただし、によって作成されたvar_nameメソッドattr_readerは引き続き使用できます。remove_method本当に必要な場合は、メソッドを削除するために使用できますvar_name(ただし、すべてを正しい順序で取得するようにしてください)。

class Foo
  attr_reader :var_name
  alias_method :reader_name, :var_name
  remove_method :var_name
  def initialize
    @var_name = 0
  end
end

本当にやりたい場合は、attr_reader_asメソッドを Module にモンキー パッチすることができます。

class Module
  def attr_reader_as(attr_name, alias_name)
    attr_reader attr_name
    alias_method alias_name, attr_name
    remove_method attr_name
  end
end

class Foo
  attr_reader_as :var_name, :reader_name
  def initialize
    @var_name = 0
  end
end

より良いattr_reader_asのはハッシュ (例: { var_name: :reader_name, var_name: :reader_name2}) を使用することですが、それは読者の演習として残しておきます。

于 2011-04-24T19:02:05.033 に答える
4

attr_reader にオプションを渡すことはできません

これはハンドコーディングですか?

class Foo
  def initialize
      @var_name = 0
  end
  def reader_name; @var_name; end
end
于 2011-04-24T18:48:05.820 に答える
3

まず、私のモットーは次のとおりです。優れたプログラマーは、チームメイトを上手に演じます。慣習に従うことは、他の人をうまく演じています。

あなたが望むものは型にはまらないようで、@edgerunner が述べているように、悪い習慣です (読んでください: 私はあなたを叩いたでしょう)。私が言っているのは、これについてよく考えてください、あなたのユースケースはわかりません、それが有効であると証明されるかもしれません.

class Foo
  include MyAttrReader
  my_attr_reader :var_name, :reader_name
  def initialize
    @var_name = 0
  end
end

かなりきれい。モジュールはトリックを行います (クラスの前にこのモジュールを必ずロードしてください)

module MyAttrReader
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def my_attr_reader(attribute, read_attribute)
      define_method "#{read_attribute}" do
        instance_variable_get "@#{attribute}"
      end
    end
  end
end

irb でのテスト

ruby-1.9.2-p180 :001 > load 'my_attr_reader.rb'
 => true 
ruby-1.9.2-p180 :002 > load 'foo.rb'
 => true 
ruby-1.9.2-p180 :003 > f = Foo.new
 => #<Foo:0x00000100979658 @var_name=0> 
ruby-1.9.2-p180 :004 > f.reader_name
 => 0 
ruby-1.9.2-p180 :005 > f.var_name
NoMethodError: undefined method `var_name' for #<Foo:0x00000100979658 @var_name=0>

これが他の人にとってどれほど直感的でないかを理解していただければ幸いです。to_s メソッドをオーバーライドして @var_name にアクセスする方法を示すこともできますが、私はそこには行きません... または var_name メソッドも定義します (2 つの getter メソッド)。規則に固執します。とにかく、とても楽しかったです、頑張ってください!

于 2011-04-24T20:44:47.820 に答える