6

I was looking through the docs for instance_variable_set and saw that the sample code given does this:

obj.instance_variable_set(:@instnc_var, "value for the instance variable")

which then allows you to access the variable as @instnc_var in any of the class's instance methods.

I'm wondering why there needs to be a colon : before the @instnc_var. What does the colon do?

you786
  • 3,659
  • 5
  • 48
  • 74

1 Answers1

11

My first instinct is to tell you not to use instance_variable_set unless you really know what you are using it for. It's essentially a tool for metaprogramming or a hack to bypass visibility of the instance variable.

That is, if there is no setter for that variable, you can use instance_variable_set to set it anyway. It's far better if you control the code to just create a setter.

Try looking at accessors for the vast majority of your instance variable setting needs. They are an idiomatic way to have getters and setters for your instance variables "for free" without you having to write those functions.

If you really do need instance_variable_set, it allows the first argument to be a symbol which is the name of the instance variable to set. A colon is part of the Ruby language that is like a "symbol literal": when you type :foo, you've created a symbol with value foo, just like when you type "bar" directly into your code, you create a string literal with value "bar".

Community
  • 1
  • 1
Matt
  • 10,434
  • 1
  • 36
  • 45
  • It's not me using it, it's the rabl library :) I'm just thinking of submitting a pull request to fix the issue I referenced, but I don't want to submit it without fully knowing why the fix works. – you786 Sep 20 '12 at 02:29
  • They *are* using it for metaprogramming, but not to change existing variables. They are creating instance variables to be used later by the user. Also, the first argument to set_instance_variable *can* be a string. – you786 Sep 20 '12 at 02:30
  • 1
    OK, thanks. The issue I 'fixed' actually turned out to be fixed because I hadn't restarted my server after updating the gem. Also, just wanted to point out that the colon is optional if the first character of the string passed in is an @ symbol. – you786 Sep 20 '12 at 03:21
  • 1
    The instance variable can also be referenced as a string: `"@a"` (or `:@a`). – Cary Swoveland Oct 28 '18 at 02:51