The Crystal Programming Language Forum

Instance variables accessors

At one point accessing an instance variable was not possible without a getter. Here is the issue discussing it.

Here is an example.

After this was changed you had to use getters to get an instance variable. This seemed to be consistent until 0.30 and then seems to start working again. Was this an intentional change?

I could not find anything in the changelog about it. Is this an intentional change or is this a regression?

IIRC this syntax exists mainly for internal reasons. It is NOT something you should do the majority of the time. It can be helpful for debugging, or very specific use cases, but I wouldn’t get into the habit of using it instead of defining a getter. If you want to expose an ivar, you should define a getter for it, esp if it is part of a public shard/API.

FWIW, both of your playground links work?

I am getting different results now on carc. I dont know what that is about.

So I read more of the issue. Is there a language feature we could add to cover this feature gap? Maybe this is just something that does not really matter. I used this feature before and supported it. The more I have used crystal and the more libs and features that have come out the less I need this feature.

Maybe all the vars are locked down by default and can be exposed with a method.

I don’t think it’s something we want to really document/spread as a language feature. It’s required for some stuff in the stdlib, not an alternative to defining getters.

I’d be curious to hear how you been using it. I think I used it about twice so far, of which that code is internal and hidden behind public APIs.

I don’t follow what exactly is the question here.

As far as I know, accessing instance variables from an external scope has always been possible. It has its use cases. For example to access unexposed ivars on other instances, which is often used in comparison methods. Or if you need to pass a pointer to a lib function, you can’t do that with a getter.
Those are all low level, internal use cases. Ivar accessors are definitely not part of any public API.

What feature gap are you talking about?

Also to add some more history, we added that because we needed it for something important back then, can’t remember what. We said we’ll later restrict its access, for example to be like protected, but we never got to doing that.

I personally think we should restrict it.

Not sure if that was the question or not.

1 Like

I personally like it. It’s not like restricting access would stop anyone getting access as you can just re-open the class and add a getter.

It might not be recommended but it’s nice that the language doesn’t go out of its way to block something you’ll be able to do anyway.


The original question is was this a regression? It seems like it is not. I originally really liked this feature but the more I have programmed in the “Crystal” way I kind of think restricting this and maybe exposing it via an API would be more crystal like. However I can see this being a low priority feature.

When I knew about it my first reaction was denial followed by a “WTF?” :laughing: Then I saw the use cases and realized that it would just make these use cases more tedious and block nothing like @stakach said, besides anyone can easily add it to a project code style. Maybe Ameba already have a rule for it.