Project

General

Profile

Actions

Feature #12495

closed

Make "private" return the arguments again, for chaining

Added by herwinw (Herwin Quarantainenet) almost 8 years ago. Updated over 2 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:76047]

Description

Ruby 2.1 introduced the feature to make def foo return the symbol, so this could be used by things like private (see #3753):

private def foo() end

You could use the same method to create your own decorators (name borrowed from Python)

def cached(name)
  # Rewrite method to include a cache
  return name
end

private cached def foo() end

Currently, this would work but cached private def foo() would not. private (and all other modifier functions) return the class on which it was called. It would be nice to exterminate those order-dependencies.

The attached patch fixes this. It includes three modes:

No arguments: return nil:

private
  def foo() end

One argument: return the symbol. The would be the most common use case for this example.

private def foo() end
private :bar

Multiple arguments: return an array of the arguments:

private :foo, :bar

Files

ruby_return_symbols_in_private.diff (1.19 KB) ruby_return_symbols_in_private.diff herwinw (Herwin Quarantainenet), 06/16/2016 07:51 AM

Updated by herwinw (Herwin Quarantainenet) almost 8 years ago

The patch is written for Ruby 2.3.1, just because the tests were broken in trunk.

Updated by nobu (Nobuyoshi Nakada) almost 8 years ago

  • Status changed from Open to Feedback

Only private, not public, protected and module_function?

Herwin Quarantainenet wrote:

The patch is written for Ruby 2.3.1, just because the tests were broken in trunk.

How broken?

Updated by herwinw (Herwin Quarantainenet) almost 8 years ago

Only private, not public, protected and module_function?

private, public and protected all use set_visibility, that's where the change is implemented, private was just used as an example. module_function/rb_mod_modfunc has not been updated, but that's an easy fix.

How broken?

Something with the openssl tests. Travis showed them red as well, but thinks it's okay by now. The comment was intended to justify any file offsets, further discussion about it would be rather irrelevant to this case.

Updated by jeremyevans0 (Jeremy Evans) over 2 years ago

  • Status changed from Feedback to Open

I think it makes sense to modify private/protected/public/module_function to be like def and return the receiver. I've submitted a pull request for this that builds on @herwinw's patch: https://github.com/ruby/ruby/pull/5037

Updated by larskanis (Lars Kanis) over 2 years ago

I stumbled several times upon this issue. The semantics as described above are OK, IMHO. It would be nice if the patch could be merged.

Updated by Eregon (Benoit Daloze) over 2 years ago

:+1:

Note there is some inconsistency with e.g. attr_reader always returning an array (#6470):

class F
  attr_reader :a # => [:a]
end

But I think it does not matter too much.

private also accepts a single Array argument since #17314, so such decorators should probably always accept either an Array or a Symbol.

Updated by matz (Yukihiro Matsumoto) over 2 years ago

Sounds OK. Accepted. The side effect should be trivial.

Matz.

Updated by baweaver (Brandon Weaver) over 2 years ago

matz (Yukihiro Matsumoto) wrote in #note-7:

Sounds OK. Accepted. The side effect should be trivial.

Matz.

Oh lovely, very fond of this idea, and had mentioned it as a warning in some of my writings around it. This will definitely be great for consistency. Give me a bit and I can have a piece out on it later, think it'll go for 3.1?

Actions #9

Updated by jeremyevans (Jeremy Evans) over 2 years ago

  • Status changed from Open to Closed

Applied in changeset git|75ecbda438670ec12641d1324d0e81a52ee02e0a.


Make Module#{public,private,protected,module_function} return arguments

Previously, each of these methods returned self, but it is
more useful to return arguments, to allow for simpler method
decorators, such as:

cached private def foo; some_long_calculation; end

Where cached sets up caching for the method.

For each of these methods, the following behavior is used:

  1. No arguments returns nil
  2. Single argument is returned
  3. Multiple arguments are returned as an array

The single argument case is really the case we are trying to
optimize for, for the same reason that def was changed to return
a symbol for the method.

Idea and initial patch from Herwin Quarantainenet.

Implements [Feature #12495]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0