Any way to make instance variables private

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):

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.

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.

1 Like

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

1 Like

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.

1 Like

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 :)

1 Like

tbh I didn’t even know this was legal syntax

2 Likes

I didn’t even knew that writing foo.@bar was possible :astonished:

5 Likes

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.

5 Likes