ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
@ 2020-09-15 20:34 marcandre-ruby-core
  2020-09-15 21:04 ` [ruby-core:100017] " marcandre-ruby-core
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: marcandre-ruby-core @ 2020-09-15 20:34 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been reported by marcandre (Marc-Andre Lafortune).

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100017] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
@ 2020-09-15 21:04 ` marcandre-ruby-core
  2020-09-15 23:18 ` [ruby-core:100018] " mame
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: marcandre-ruby-core @ 2020-09-15 21:04 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by marcandre (Marc-Andre Lafortune).


I'd like us to consider changing this so that `private` also changes the visibility of future constants being set.

If that is deemed too risky for compatibility, could `private_constant` with no receiver do this?

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-87570

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100018] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
  2020-09-15 21:04 ` [ruby-core:100017] " marcandre-ruby-core
@ 2020-09-15 23:18 ` mame
  2020-09-16 21:13 ` [ruby-core:100027] " eregontp
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: mame @ 2020-09-15 23:18 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by mame (Yusuke Endoh).


I think your expectation is reasonable. If we change it, we need much work to estimate its compatibility impact carefully and to design a migration path, of course.

I proposed and implemented `private_constant` ten years ago.  [Feature #2366] was written in Japanese (sorry!), but as far as I see, no one discussed changing `private`, maybe because of compatibility. I did not introduce `private_constant` with no receiver was because I wanted to avoid a new module state (as I recall, matz now dislikes the module state), but I agree that it is redundant.

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-87571

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100027] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
  2020-09-15 21:04 ` [ruby-core:100017] " marcandre-ruby-core
  2020-09-15 23:18 ` [ruby-core:100018] " mame
@ 2020-09-16 21:13 ` eregontp
  2020-09-17  7:36 ` [ruby-core:100029] " jean.boussier
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: eregontp @ 2020-09-16 21:13 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by Eregon (Benoit Daloze).


mame (Yusuke Endoh) wrote in #note-3:
> I did not introduce `private_constant` with no receiver because I wanted to avoid a new module state (as I recall, matz now dislikes the module state), but I agree that it is redundant.

Interesting, is `private` implemented as state on the module? (but then would need to be thread-local when concurrently loading or so)
I always thought it's part of the state stored in the frame.

Regarding the issue, I agree it would be nice.
Maybe we can make an experiment and gather feedback from gems testing against ruby-head?

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-87578

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100029] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
                   ` (2 preceding siblings ...)
  2020-09-16 21:13 ` [ruby-core:100027] " eregontp
@ 2020-09-17  7:36 ` jean.boussier
  2020-09-29 17:08 ` [ruby-core:100220] " shevegen
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jean.boussier @ 2020-09-17  7:36 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by byroot (Jean Boussier).


I agree too that it would be much cleaner, I keep seeing newer Ruby developers expecting it to work that way. That and `def self.something`.

> Maybe we can make an experiment and gather feedback from gems testing against ruby-head?

I can already tell you without a doubt it will break lots of code. What scares me is that since it would need to go through a deprecation cycle, and would be quite noisy, it has the potential to create a backlash like the keyword args change did. But maybe it wouldn't be as verbose?

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-87580

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100220] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
                   ` (3 preceding siblings ...)
  2020-09-17  7:36 ` [ruby-core:100029] " jean.boussier
@ 2020-09-29 17:08 ` shevegen
  2020-10-16  3:55 ` [ruby-core:100414] " marcandre-ruby-core
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: shevegen @ 2020-09-29 17:08 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by shevegen (Robert A. Heiler).


I am not quite as active on the bug-tracker as I used to be in the past, but I will comment on this particular issue since the reasoning given makes sense to me.

I will not comment on the backwards-incompatibility issue much at all, but let me state that I feel that the backwards-incompatibility is a separate consideration to make. For example, matz could approve of the idea here (if he agrees on it), but decide to delay changes here to some later stage for some ruby 3.x release in the future, or perhaps 4.0. There are quite a few changes that may come past ruby 3.0 anyway, but I feel that for this particular discussion here, it may be better to separate between the issue itself ("make constants private too"), and any incompatibility issue as a secondary consideration IF the proposed change would receive the "go-ahead" signal. Otherwise we may have problems discussing and changing anything, because the fear of incompatibility prevents any change, which would be bad too, in particular past ruby 3.0.

I also think that a deprecation period is perfectly fine, so I disagree with byroot; I also don't think it has the same impact as keyword arguments or frozen strings. Do note that I do not disagree with his comment that this may lead to broken code - yep, this is most likely true. I just think that a deprecation time is perfectly viable IF matz decides to approve this proposal. For example, when frozen strings were introduced, just about none of my ruby code would have worked. Nowadays, all my ruby code works 100% with frozen strings (or, say, 99.5%; I have not ported ALL my old ruby code, but I can easily do so step by step, so it really is a non-issue to me). And here, a deprecation time did help. So I disagree with byroot on that particular note - I think deprecation would be perfectly fine. Just give people some time to adjust their code, it will slowly happen. Make sure to communicate this too, because not everyone reads the bugtracker. :)

So, next, I will focus only on the suggestion itself, without consideration for backwards incompatibility.

-------------------------------------------------------------------------------

Let me "preface" this by saying that I don't often use "private". I also don't use .public_send(). To me .send() is more logical, and "private" is also not quite as logical - but this may depend on the OOP style that one uses. For example, Java users may perhaps prefer a stricter distinction whereas smalltalk users may prefer more unrestricted objects; I can understand that.

At any rate, while I am not really the target audience for the proposed change, and while I am not a big fan of "private" in general (by the way, nobody mentions "protected" ... hahaha :D), what marcandre writes still makes a LOT of sense to me.

Why is that so?

Well, simple.

Consider a .rb file where the ruby developer writes "private" in the middle of that .rb file, just as shown by marcandre in the example above (we can ignore the CONSTANT for the moment). Ok, we can expect that all methods past that point are now "private" too, thus more restricted than by default. That is the natural way to use private, yes?

IF if you come from THAT point of view, where the simple use of "private" switches the other methods that follow towards the state of "more restrictions" than the default "public" does, then actually what marcandre writes, makes a LOT of sense to me as well.

- If the methods are private, why not the constants too? Makes sense what is written there really.

You can of course say that constants and methods are not directly linked, yes; perhaps "private" implies more "private_method" only. I am not so sure, but let's just assume this for the moment, that a ruby user could specifically want _ONLY_ the methods to be private, and _NOT_ the constants.
 
And we can have longer APIs, such as "private_method" and "private_constant" perhaps - I feel this is a bit separate to the issue at hand, though. Aka, what "private" really means in this context.

So, the key question then is:

- What does "private" entail, and, following this
- How much control should ruby users have over ruby code in this regard?

The second part in particular feels 100% like a language design choice, so for matz to decide.

Even then, though, I think it makes a lot of sense to me here what marcandre wrote. I think this will apply by far to most ruby code as well out there, if they use "private" in this way - at the least as an intention. The intention seems to clearly be to put all methods into a "more restricted" state. (Yes, some older ruby code may have problems, as byroot pointed out, but that is a separate consideration to make, in my opinion.)

IF the ruby user uses "private" in the way shown by marcandre, to me it also means that the user is saying something like this:

    "Ruby, please, I would like to have all the code that follows there to be more restricted, to avoid funky outside use of this code".

And to me, if this instruction given to ruby is true, then it would also make a lot of sense to apply this restriction to constants just as well, if you come from that point of view or a similar point of view.

I can not say whether that was the same point of view marcandre used, but I come to the same conclusion in the end, so +1 from my side on that proposed change. To me it seems "logical" (even if it may not be logical per se, but I think marcandre is right; most people may probably assume that a restriction should occur, IF private is used in that manner. And that is coming from someone who rarely uses private; I just feel it really makes sense, since it will capture the intention of most ruby users IMO.)

So, TL;DR, +1 from me.

-------------------------------------------------------------------------------


----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-87809

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100414] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
                   ` (4 preceding siblings ...)
  2020-09-29 17:08 ` [ruby-core:100220] " shevegen
@ 2020-10-16  3:55 ` marcandre-ruby-core
  2020-10-16  4:19 ` [ruby-core:100415] " merch-redmine
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: marcandre-ruby-core @ 2020-10-16  3:55 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by marcandre (Marc-Andre Lafortune).


So can we envision issuing a warning for two release cycles?

Is it feasible to issue a warning for constants that are currently public that would be made private this way?

Difficult being that call to `private_constant` happens after point of definition:

```ruby
class Foo
  private
  X = 42
end # => Warn about privacy change

class Bar
  private
  X = 42
  private_constant :X
end # => No warning
```


----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-88029

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100415] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
                   ` (5 preceding siblings ...)
  2020-10-16  3:55 ` [ruby-core:100414] " marcandre-ruby-core
@ 2020-10-16  4:19 ` merch-redmine
  2020-10-16  5:26 ` [ruby-core:100416] " marcandre-ruby-core
  2020-10-26  7:52 ` [ruby-core:100561] " matz
  8 siblings, 0 replies; 10+ messages in thread
From: merch-redmine @ 2020-10-16  4:19 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by jeremyevans0 (Jeremy Evans).


marcandre (Marc-Andre Lafortune) wrote in #note-7:
> So can we envision issuing a warning for two release cycles?
> 
> Is it feasible to issue a warning for constants that are currently public that would be made private this way?
> 
> Difficult being that call to `private_constant` happens after point of definition:
> 
> ```ruby
> class Foo
>   private
>   X = 42
> end # => Warn about privacy change
> 
> class Bar
>   private
>   X = 42
>   private_constant :X
> end # => No warning
> ```

I think if we do this, we should only warn on access (i.e. `Foo::X`), not definition.  This would require internal changes to add a sort of deprecated-public visibility.

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-88030

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100416] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
                   ` (6 preceding siblings ...)
  2020-10-16  4:19 ` [ruby-core:100415] " merch-redmine
@ 2020-10-16  5:26 ` marcandre-ruby-core
  2020-10-26  7:52 ` [ruby-core:100561] " matz
  8 siblings, 0 replies; 10+ messages in thread
From: marcandre-ruby-core @ 2020-10-16  5:26 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by marcandre (Marc-Andre Lafortune).


Deprecating on access (first time only) would be less noisy and sounds easier to implement indeed 👍

----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-88031

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```ruby

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [ruby-core:100561] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`?
  2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
                   ` (7 preceding siblings ...)
  2020-10-16  5:26 ` [ruby-core:100416] " marcandre-ruby-core
@ 2020-10-26  7:52 ` matz
  8 siblings, 0 replies; 10+ messages in thread
From: matz @ 2020-10-26  7:52 UTC (permalink / raw)
  To: ruby-core

Issue #17171 has been updated by matz (Yukihiro Matsumoto).

Status changed from Open to Rejected

This looks very interesting, but it would introduce quite big incompatibility. I don't want to break existing code.

Matz.


----------------------------------------
Feature #17171: Why is the visibility of constants not affected by `private`?
https://bugs.ruby-lang.org/issues/17171#change-88191

* Author: marcandre (Marc-Andre Lafortune)
* Status: Rejected
* Priority: Normal
----------------------------------------
```ruby
class Foo
  def call_me
    # ...
  end

  private
 
  SOME_DATA = %i[...].freeze  # is public, why not private?

  def calc_stuff  # is private, ok.
    # ...
  end
end
```

It's probably a naive question, but why shouldn't `SOME_DATA`'s visibility be private?

When writing gems, more often than not the constants that I write are not meant for public consumption. I find it redundant (and tiresome) to explicitly write `private_constant :SOME_DATA`.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-10-26  7:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-15 20:34 [ruby-core:100016] [Ruby master Feature#17171] Why is the visibility of constants not affected by `private`? marcandre-ruby-core
2020-09-15 21:04 ` [ruby-core:100017] " marcandre-ruby-core
2020-09-15 23:18 ` [ruby-core:100018] " mame
2020-09-16 21:13 ` [ruby-core:100027] " eregontp
2020-09-17  7:36 ` [ruby-core:100029] " jean.boussier
2020-09-29 17:08 ` [ruby-core:100220] " shevegen
2020-10-16  3:55 ` [ruby-core:100414] " marcandre-ruby-core
2020-10-16  4:19 ` [ruby-core:100415] " merch-redmine
2020-10-16  5:26 ` [ruby-core:100416] " marcandre-ruby-core
2020-10-26  7:52 ` [ruby-core:100561] " matz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).