Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop globals, make all variables starting with $ pseudo globals aka magic variables #1395

Closed
jhass opened this issue Sep 6, 2015 · 5 comments

Comments

@jhass
Copy link
Member

jhass commented Sep 6, 2015

Let's say it: we don't need globals. There are plentiful alternatives to global state and all of them are to prefer. Let's list a few:

# Alternative 1, classic singleton
class Foo
  def self.instance
    new
  end
end

# Alternative 2, module level class variables
# Usually you have some library namespace, we can use that!
module MyLib
  @@foo = initial
  def self.foo
    @@foo
  end

  def self.foo=(value)
    @@foo = value
  end
end

# Alternative 3: "You meant to use a constant"
# Most global usage I observe is perfectly fine with using a constant
# pointing to a mutable datastructure
Foo = {} of String => String

Now we would want to keep $?, $~ and so on, as previously discussed. Let's call them magic variables. But now we got all names starting with $ free, let's allow to define magic variables with any name.

Magic variables...

  • can't be defined on the toplevel or class/module level, only inside methods.
  • are visible in the direct caller scope, but not in the scope of the caller's caller.
  • are visible in the method defining them, but not inside subsequent calls.
  • can be passed on by the caller to its caller by reassigning them to themselves, $foo = $foo. This fails if there wasn't a call defining $foo prior.

The name magic variable suggest that this is still something to be used with care, not as go to tool over multiple return using a tuple or returning a nice struct. It just replaces the, in a object oriented language, useless concept of global variables with something more useful, while removing inconsistency from the language between pseudo globals ($~, $? etc) and global variables.

@jhass jhass added the RFC label Sep 6, 2015
@will
Copy link
Contributor

will commented Sep 7, 2015

I'm in favor (somewhere less than "strongly in favor") of dropping globals, but can you go into the motivations for the things in the bulleted list?

@jhass
Copy link
Member Author

jhass commented Sep 7, 2015

It's essentially the behaviour of the pseudo globals, I just listed it out. Since we want to keep this my proposal is to make all $vars behave that way.

@asterite
Copy link
Member

asterite commented Sep 7, 2015

I would drop globals and just keep the few special variables. As their name imply, they are "special" and I wouldn't like having more of those.

On the other hand, globals are pretty useful for counting global things in a program, for example how many times a method was invoked, or benchmarking a single method across a whole program, by writing to a global. These are not "serious" use cases, but practical. They could still be done with a class variable, but you need to write a bit more.

@jhass
Copy link
Member Author

jhass commented Sep 7, 2015

We can also add things like class_property, reducing the overhead to two lines of code and a namespace on the caller side.

module MyLib
  class_property! foo
end

@asterite
Copy link
Member

I think this can be closed. We don't have globals anymore. We have some magic vars like $1 and $! but we don't want to have general-purpose magic vars as they make code harder to understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants