Why instance variables can be modified through a field reader with the << operator?












1














Consider the following class.



class Test
attr_reader :word
def initialize(word)
@word = word
end

def append_word(token)
word << token
end
end


Consider a sample usage of the class.



2.4.0 :001 > t = Test.new('Hello')
=> #<Test:0x007f7f09902970 @word="Hello">
2.4.0 :002 > t.append_word(' world!')
=> "Hello world!"
2.4.0 :003 > t.word
=> "Hello world!"
2.4.0 :004 >


I am new to Ruby. I don't understand why I can use the append_word instance method to modify the instance variable @word of a Test instance. word in append_word seems to be a field reader. My understanding is that a field reader is for reading only. How can word << token in append_word modify the value of @word in a Test instance?










share|improve this question



























    1














    Consider the following class.



    class Test
    attr_reader :word
    def initialize(word)
    @word = word
    end

    def append_word(token)
    word << token
    end
    end


    Consider a sample usage of the class.



    2.4.0 :001 > t = Test.new('Hello')
    => #<Test:0x007f7f09902970 @word="Hello">
    2.4.0 :002 > t.append_word(' world!')
    => "Hello world!"
    2.4.0 :003 > t.word
    => "Hello world!"
    2.4.0 :004 >


    I am new to Ruby. I don't understand why I can use the append_word instance method to modify the instance variable @word of a Test instance. word in append_word seems to be a field reader. My understanding is that a field reader is for reading only. How can word << token in append_word modify the value of @word in a Test instance?










    share|improve this question

























      1












      1








      1







      Consider the following class.



      class Test
      attr_reader :word
      def initialize(word)
      @word = word
      end

      def append_word(token)
      word << token
      end
      end


      Consider a sample usage of the class.



      2.4.0 :001 > t = Test.new('Hello')
      => #<Test:0x007f7f09902970 @word="Hello">
      2.4.0 :002 > t.append_word(' world!')
      => "Hello world!"
      2.4.0 :003 > t.word
      => "Hello world!"
      2.4.0 :004 >


      I am new to Ruby. I don't understand why I can use the append_word instance method to modify the instance variable @word of a Test instance. word in append_word seems to be a field reader. My understanding is that a field reader is for reading only. How can word << token in append_word modify the value of @word in a Test instance?










      share|improve this question













      Consider the following class.



      class Test
      attr_reader :word
      def initialize(word)
      @word = word
      end

      def append_word(token)
      word << token
      end
      end


      Consider a sample usage of the class.



      2.4.0 :001 > t = Test.new('Hello')
      => #<Test:0x007f7f09902970 @word="Hello">
      2.4.0 :002 > t.append_word(' world!')
      => "Hello world!"
      2.4.0 :003 > t.word
      => "Hello world!"
      2.4.0 :004 >


      I am new to Ruby. I don't understand why I can use the append_word instance method to modify the instance variable @word of a Test instance. word in append_word seems to be a field reader. My understanding is that a field reader is for reading only. How can word << token in append_word modify the value of @word in a Test instance?







      ruby






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 3:09









      Isaac To

      907




      907
























          1 Answer
          1






          active

          oldest

          votes


















          5














          Your @word references an object in memory. This object happens to be a Hello! string. Your class does not allow to (easily) set a new object for your @word instance variable, but nothing currently stops you from modifying the object directly. If you wish for the object to not be modifiable, you could .freeze it:



          class Test
          attr_reader :word
          def initialize(word)
          @word = word.freeze
          end

          def append_word(token)
          word << token
          end
          end

          > Test.new("Hello").append_word("world!")
          # FrozenError (can't modify frozen String)





          share|improve this answer





















          • Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
            – Isaac To
            Nov 13 '18 at 6:43










          • Yes, attr_reader :word is the same as def word; @word; end
            – Marcin Kołodziej
            Nov 13 '18 at 6:44






          • 1




            Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
            – Amadan
            Nov 13 '18 at 7:15












          • @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
            – Marcin Kołodziej
            Nov 13 '18 at 13:56










          • @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
            – Isaac To
            Nov 13 '18 at 22:32











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53273208%2fwhy-instance-variables-can-be-modified-through-a-field-reader-with-the-operat%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          5














          Your @word references an object in memory. This object happens to be a Hello! string. Your class does not allow to (easily) set a new object for your @word instance variable, but nothing currently stops you from modifying the object directly. If you wish for the object to not be modifiable, you could .freeze it:



          class Test
          attr_reader :word
          def initialize(word)
          @word = word.freeze
          end

          def append_word(token)
          word << token
          end
          end

          > Test.new("Hello").append_word("world!")
          # FrozenError (can't modify frozen String)





          share|improve this answer





















          • Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
            – Isaac To
            Nov 13 '18 at 6:43










          • Yes, attr_reader :word is the same as def word; @word; end
            – Marcin Kołodziej
            Nov 13 '18 at 6:44






          • 1




            Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
            – Amadan
            Nov 13 '18 at 7:15












          • @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
            – Marcin Kołodziej
            Nov 13 '18 at 13:56










          • @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
            – Isaac To
            Nov 13 '18 at 22:32
















          5














          Your @word references an object in memory. This object happens to be a Hello! string. Your class does not allow to (easily) set a new object for your @word instance variable, but nothing currently stops you from modifying the object directly. If you wish for the object to not be modifiable, you could .freeze it:



          class Test
          attr_reader :word
          def initialize(word)
          @word = word.freeze
          end

          def append_word(token)
          word << token
          end
          end

          > Test.new("Hello").append_word("world!")
          # FrozenError (can't modify frozen String)





          share|improve this answer





















          • Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
            – Isaac To
            Nov 13 '18 at 6:43










          • Yes, attr_reader :word is the same as def word; @word; end
            – Marcin Kołodziej
            Nov 13 '18 at 6:44






          • 1




            Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
            – Amadan
            Nov 13 '18 at 7:15












          • @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
            – Marcin Kołodziej
            Nov 13 '18 at 13:56










          • @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
            – Isaac To
            Nov 13 '18 at 22:32














          5












          5








          5






          Your @word references an object in memory. This object happens to be a Hello! string. Your class does not allow to (easily) set a new object for your @word instance variable, but nothing currently stops you from modifying the object directly. If you wish for the object to not be modifiable, you could .freeze it:



          class Test
          attr_reader :word
          def initialize(word)
          @word = word.freeze
          end

          def append_word(token)
          word << token
          end
          end

          > Test.new("Hello").append_word("world!")
          # FrozenError (can't modify frozen String)





          share|improve this answer












          Your @word references an object in memory. This object happens to be a Hello! string. Your class does not allow to (easily) set a new object for your @word instance variable, but nothing currently stops you from modifying the object directly. If you wish for the object to not be modifiable, you could .freeze it:



          class Test
          attr_reader :word
          def initialize(word)
          @word = word.freeze
          end

          def append_word(token)
          word << token
          end
          end

          > Test.new("Hello").append_word("world!")
          # FrozenError (can't modify frozen String)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 3:13









          Marcin Kołodziej

          4,2611315




          4,2611315












          • Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
            – Isaac To
            Nov 13 '18 at 6:43










          • Yes, attr_reader :word is the same as def word; @word; end
            – Marcin Kołodziej
            Nov 13 '18 at 6:44






          • 1




            Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
            – Amadan
            Nov 13 '18 at 7:15












          • @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
            – Marcin Kołodziej
            Nov 13 '18 at 13:56










          • @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
            – Isaac To
            Nov 13 '18 at 22:32


















          • Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
            – Isaac To
            Nov 13 '18 at 6:43










          • Yes, attr_reader :word is the same as def word; @word; end
            – Marcin Kołodziej
            Nov 13 '18 at 6:44






          • 1




            Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
            – Amadan
            Nov 13 '18 at 7:15












          • @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
            – Marcin Kołodziej
            Nov 13 '18 at 13:56










          • @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
            – Isaac To
            Nov 13 '18 at 22:32
















          Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
          – Isaac To
          Nov 13 '18 at 6:43




          Thanks. Your post answered my question. However, it brought up another. Does Ruby guarantee that word, the field reader, refers to the exact same object referred by @word instead of a copy of the object referred by @word?
          – Isaac To
          Nov 13 '18 at 6:43












          Yes, attr_reader :word is the same as def word; @word; end
          – Marcin Kołodziej
          Nov 13 '18 at 6:44




          Yes, attr_reader :word is the same as def word; @word; end
          – Marcin Kołodziej
          Nov 13 '18 at 6:44




          1




          1




          Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
          – Amadan
          Nov 13 '18 at 7:15






          Technically, Ruby does have some types that are not full objects (by the fact their values are not references), though they behave as objects for most intents and purposes. For example, if @word is a small integer, word will return a copy and not a reference (as these objects are never referenced). However, since all such quasi-objects are immutable, there is no situation where a copy will behave differently than a reference, so it's a moot point.
          – Amadan
          Nov 13 '18 at 7:15














          @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
          – Marcin Kołodziej
          Nov 13 '18 at 13:56




          @Amadan true, also worth mentioning that in case of these immutable objects, calling @word also returns a copy of @word, therefore adding a attr_reader does not really change how you interact with underlying value.
          – Marcin Kołodziej
          Nov 13 '18 at 13:56












          @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
          – Isaac To
          Nov 13 '18 at 22:32




          @Amadan Does Ruby guarantee that all mutable objects are passed by reference?
          – Isaac To
          Nov 13 '18 at 22:32


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53273208%2fwhy-instance-variables-can-be-modified-through-a-field-reader-with-the-operat%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Bressuire

          Vorschmack

          Quarantine