# Any way to make instance variables private

**URL:** <https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257>\
**Category:** Help & Support\
**Created:** [May 2, 2021, 6:03am UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257 "2021-05-02T06:03:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![code-shoily](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/code-shoily/32/1251_2.png) [@code-shoily](https://forum.crystal-lang.org/u/code-shoily)\
**Post date:** [May 2, 2021, 6:03am UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/1 "2021-05-02T06:03:12Z")

</div>

I wanted to know if there is a way we can make instance variables inaccessible outside of the class. For example, the following snippet (which works and prints 30):

```crystal
class Point
  @x : Int32
  @y : Int32
  
  def initialize(@x, @y)
  end
end
  
point = Point.new(10, 20)
  
puts point.@x + point.@y

```

What if I wanted `@x` and `@y` not be accessible from outside the class if I do not define any `getter` or `property`. I think I read in a discussion that instance variables are private by default, is that only in case of writes?

Thanks in advance. I just started learning Crystal two days ago so if I have missed the obvious then apologies in advance too.

---

<div class="post-metadata">

**Author:** ![erdnaxeli](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/erdnaxeli/32/1242_2.png) [@erdnaxeli](https://forum.crystal-lang.org/u/erdnaxeli)\
**Post date:** [May 2, 2021, 9:07am UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/2 "2021-05-02T09:07:58Z")

</div>

There is no way to do that. Instance variables are actually public, but you should write code as if they were private. So here you should use two getters.

---

<div class="post-metadata">

**Author:** ![jhass](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jhass/32/1779_2.png) [@jhass](https://forum.crystal-lang.org/u/jhass)\
**Post date:** [May 2, 2021, 9:17am UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/3 "2021-05-02T09:17:03Z")

</div>

Put differently, accessing instance variables directly is a smell and should be avoided 99.9% of the time.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [May 2, 2021, 9:40am UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/4 "2021-05-02T09:40:45Z")

</div>

Even if we remove the syntax to access an instance variable from outside of a class, anyone can reopen your class and add getters for them. In Ruby this is almost the same, you have a method called instamcr\_variable\_get.

---

<div class="post-metadata">

**Author:** ![code-shoily](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/code-shoily/32/1251_2.png) [@code-shoily](https://forum.crystal-lang.org/u/code-shoily)\
**Post date:** [May 2, 2021, 12:35pm UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/5 "2021-05-02T12:35:57Z")

</div>

Thank you very much everyone, I titally agree and just wanted to verify. This code smell has a pretty strong scent since a `.@` will give it away upon visual inspection. The 0.01% of the time I can see myself using it is when I’m debugging and even that would be temporary.

It’s awesome to have replies so fast. Y’all are awesome :)

---

<div class="post-metadata">

**Author:** ![TheOneAndOnly](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/theoneandonly/32/1152_2.png) [@TheOneAndOnly](https://forum.crystal-lang.org/u/TheOneAndOnly)\
**Post date:** [May 3, 2021, 2:16pm UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/6 "2021-05-03T14:16:30Z")

</div>

tbh I didn’t even know this was legal syntax

---

<div class="post-metadata">

**Author:** ![hugopl](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hugopl/32/970_2.png) [@hugopl](https://forum.crystal-lang.org/u/hugopl)\
**Post date:** [May 3, 2021, 2:31pm UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/7 "2021-05-03T14:31:11Z")

</div>

I didn’t even knew that writing `foo.@bar` was possible 😲

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [May 3, 2021, 2:45pm UTC](https://forum.crystal-lang.org/t/any-way-to-make-instance-variables-private/3257/8 "2021-05-03T14:45:58Z")

</div>

I think we should probably document it as a current behavior that you shouldn’t rely on, even if it’s a breaking change.

Ideally, I’d like that syntax to only be able to access instance variables of the same scope.
