Here is my immature opinion. If I am wrong, please correct me.
Suppose instance variables do not have the @ prefix, then how do we declare an instance variable?
class MyClass def initialize
In the above case, the instance variable foo initialized using a hypothetical syntax
self.foo = 'bar'
because we must have a way to tell the ruby interpreter that foo belongs to the current instance and is not a local variable.
Then in the bar method, if the brackets are not involved in the method call, how can the interpreter indicate whether self.foo method call or access to an instance variable?
Maybe we can allow shadow instances of instance variables in the absence of brackets, but this leads to inconsistent syntax of the language itself. For example, because of the scope of the definition of MyClass :
obj = MyClass.new
This is an instance method call because all instance variables are invisible from the outside (at least without the use of metaprograms). But self.foo (without parentheses) in the bar method is access to the instance variable. This syntax inconsistency can lead to errors. In addition, this makes it difficult to implement the interpreter itself.
. What about allowing instance methods to shadow instance variables? Programmers then need to make sure that the instance variable names do not interfere with the instance instance names, otherwise the instance variables become unavailable. It is very difficult if a class has a long chain of ancestors, because collisions need to be checked not only in the current definition of the class, but also for its ancestors, and this violates encapsulation.
In any case, the price is much higher than adding a prefix to instance variables. For classes and global variables, the situations are similar.