Tags

  • AWS (7)
  • Apigee (3)
  • ArchLinux (5)
  • Array (6)
  • Backtracking (6)
  • BinarySearch (6)
  • C++ (19)
  • CI&CD (3)
  • Calculus (2)
  • DesignPattern (43)
  • DisasterRecovery (1)
  • Docker (8)
  • DynamicProgramming (20)
  • FileSystem (11)
  • Frontend (2)
  • FunctionalProgramming (1)
  • GCP (1)
  • Gentoo (6)
  • Git (15)
  • Golang (1)
  • Graph (10)
  • GraphQL (1)
  • Hardware (1)
  • Hash (1)
  • Kafka (1)
  • LinkedList (13)
  • Linux (27)
  • Lodash (2)
  • MacOS (3)
  • Makefile (1)
  • Map (5)
  • MathHistory (1)
  • MySQL (21)
  • Neovim (10)
  • Network (66)
  • Nginx (6)
  • Node.js (33)
  • OpenGL (6)
  • PriorityQueue (1)
  • ProgrammingLanguage (9)
  • Python (10)
  • RealAnalysis (20)
  • Recursion (3)
  • Redis (1)
  • RegularExpression (1)
  • Ruby (19)
  • SQLite (1)
  • Sentry (3)
  • Set (4)
  • Shell (3)
  • SoftwareEngineering (12)
  • Sorting (2)
  • Stack (4)
  • String (2)
  • SystemDesign (13)
  • Terraform (2)
  • Tree (24)
  • Trie (2)
  • TwoPointers (16)
  • TypeScript (3)
  • Ubuntu (4)
  • Home

    attr_accessor in Ruby

    Published Jul 01, 2020 [  Ruby  ]

    Let’s say you have a class Person

    class Person
    end
    
    person = Person.new
    person.name # => no method error
    

    Obviously we never defined method name. Let’s do that

    class Person
      def name
        @name # simply returning an instance variable @name
      end
    end
    
    person = Person.new
    person.name # => nil
    person.name = "Dennis" # => no method error
    

    Aha, we can read the name, but that doesn’t mean we can assign the name. Those are two different methods. The former is called reader and latter is called writer. We didn’t create the write yet so let’s do that.

    class Person
      def name
        @name
      end
    
      def name=(str)
        @name = str
      end
    end
    
    person = Person.new
    person.name = 'Dennis'
    person.name # => "Dennis"
    

    Awesome. Now we can write and read instance variable @name using reader and writer methods. Except, this is done so frequently, why waste time writing these methods every time? We can do it easier.

    class Person
      attr_reader :name
      attr_writer :name
    end
    

    Even this can get repetitive. When you want both reader and writer just use accessor!

    class Person
      attr_accessor :name
    end
    
    person = Person.new
    person.name = "Dennis"
    person.name # => "Dennis"
    

    Works the same way! And guess what: the instance variable @name in our person object will be set just like when we did it manually, so you can use it in other methods.

    class Person
      attr_accessor :name
    
      def greeting
        "Hello #{@name}"
      end
    end
    
    person = Person.new
    person.name = "Dennis"
    person.greeting # => "Hello Dennis"
    

    That’s it.

    Simple implementation

    class Module
      def var( method_name )
        inst_variable_name = "@#{method_name}".to_sym
        define_method method_name do
          instance_variable_get inst_variable_name
        end
        define_method "#{method_name}=" do |new_value|
          instance_variable_set inst_variable_name, new_value
        end
      end
    end
    
    class Foo
      var :bar
    end
    
    f = Foo.new
    p f.bar     #=> nil
    f.bar = 42
    p f.bar     #=> 42
    

    References