Search code examples
rubyattributesconventionsstandard-library

Is there a way to make attr_reader create methods with a different name than the instance variable?


In Ruby, is there a way to do something like

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

In other words, is there a standard way to make an accessor method for a variable that uses a different name than the variable. (Besides hand-coding it, of course.)


Solution

  • You could use alias_method:

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

    The var_name method built by attr_reader would still be available though. You could use remove_method to get rid of the var_name method if you really wanted to (but make sure you get everything in the right order):

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

    If you really wanted to, you could monkey patch an attr_reader_as method into 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
    

    A better attr_reader_as would take a hash (e.g. { var_name: :reader_name, var_name: :reader_name2}) but I'll leave that as an exercise for the reader.