2

Is there any way to protect an instance variable from being written to/modified in Ruby?

Say I do this:

class Test
  def initialize(var)
   @var = var
  end

  def modify
   @var = "test" # This would raise an error, saying '@var' is just readable.
  end
end

Is there any way to make instance variable to be read-only? If not, which kind of attribute am I looking for?

3
  • 1
    Even constants in ruby are not write-protected. What is your bigger use case which forced you to raise this question? Commented Nov 18, 2013 at 5:48
  • 1
    Just experimenting with Ruby and wondering quite a lot of things :) Commented Nov 18, 2013 at 5:50
  • 1
    You must be a C programmer to ask such a question in ruby, I had the same confusions when I started learning it. Commented Nov 18, 2013 at 5:51

3 Answers 3

4

You can virtually protect instance variables with freezing a wrapping object:

t=Test.new "example"
p t.var
# "example"
t.freeze
t.modify
# :in `modify': can't modify frozen Test (RuntimeError)
p t.var
# t.var is still equal to "example" if exception won't terminate app

See Object#freeze method for details.

Sign up to request clarification or add additional context in comments.

1 Comment

This is impressive answer. I have come up with similar(freezing self) solution. However, you don't protect variables but object of (in this case)class Test. You cannot add, delete, modify pointers but you can modify in place - data that those pointers refer too(C terms). In order to really protect you must freeze variable itself. Check this: gist.github.com/nedzadarek/7536766
2

There is no way to do that. First of all, there should not be a reason that a class would need to write-protect an attribute against itself. Secondly, all access protection rules in Ruby, such as it exists, are really only suggestions - ultimately, using introspection, you can access anything you wish, including redefining core methods like Fixnum#+. Try this:

class Fixnum
  def +(other)
    self - other
  end
end

It will mess up your code more than writing to @var ever could.

1 Comment

Don't try it in pry! It will start spiting some messages in endless loop. btw. def 2.ff; end
0

No, there is no way to do this. The closest thing Ruby has to non-writable variables are constants which can exist within a class or module and begin with a capital letter (typically all caps). Ruby will not prevent these variables from being written, but will issue a warning if they are redefined.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.