Project

General

Profile

Bug #13592

Enumerable#reduce with symbol does not respect method visibility

Added by americodls (Americo Duarte) over 2 years ago. Updated over 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin15]
[ruby-core:81349]

Description

When use reduce with symbol, I expect the symbol is called in object but respecting the method visibility.

Example with source code written in a file.

Fixnum.instance_eval do
  private :+
end

p [1,2,3].reduce(:+)

The behavior in IRB is different.

irb(main):001:0> [1,2,3].reduce(:+)
=> 6
irb(main):002:0> Fixnum.instance_eval do
irb(main):003:1*   private :+
irb(main):004:1> end
=> Fixnum
irb(main):005:0>
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/irb/input-method.rb:154:in `gets': private method `+' called for 4:Fixnum (NoMethodError)

Now, I am confused. Those behaviors are expected? In doc this is not clear.

Associated revisions

Revision 5e25bfa2
Added by nobu (Nobuyoshi Nakada) over 2 years ago

enum.c: respect method visibility

  • enum.c (ary_inject_op): should respect method visibility, do not optimize uncallable method. [ruby-core:81349] [Bug #13592]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 58871
Added by nobu (Nobuyoshi Nakada) over 2 years ago

enum.c: respect method visibility

  • enum.c (ary_inject_op): should respect method visibility, do not optimize uncallable method. [ruby-core:81349] [Bug #13592]

Revision 58871
Added by nobu (Nobuyoshi Nakada) over 2 years ago

enum.c: respect method visibility

  • enum.c (ary_inject_op): should respect method visibility, do not optimize uncallable method. [ruby-core:81349] [Bug #13592]

Revision 58871
Added by nobu (Nobuyoshi Nakada) over 2 years ago

enum.c: respect method visibility

  • enum.c (ary_inject_op): should respect method visibility, do not optimize uncallable method. [ruby-core:81349] [Bug #13592]

History

Updated by americodls (Americo Duarte) over 2 years ago

Sorry, ignore the IRB thing. But my question about the reduce still valid.

Updated by nobu (Nobuyoshi Nakada) over 2 years ago

  • Status changed from Open to Rejected
  • Description updated (diff)

The proc returned by Symbol#to_proc is equivalent to proc {|recv, *args| recv.__send__(self, *args)}.
So it can call private methods too.

Updated by americodls (Americo Duarte) over 2 years ago

  • Status changed from Rejected to Feedback

Please, reconsider. Look this example:

irb(main):092:0> :puts.to_proc.call("")
NoMethodError: private method `puts' called for "":String

nobu (Nobuyoshi Nakada) wrote:

The proc returned by Symbol#to_proc is equivalent to proc {|recv, *args| recv.__send__(self, *args)}.
So it can call private methods too.

#4

Updated by americodls (Americo Duarte) over 2 years ago

  • Status changed from Feedback to Open

Updated by Hanmac (Hans Mackowiak) over 2 years ago

reduce(&:+) is different from
reduce(:+), this one has nothing to do with :+.to_proc

reduce/inject with symbol param does call the method internally without checking if its private or not

Updated by americodls (Americo Duarte) over 2 years ago

This is exactly what I am saying.

This behavior of reduce is unpredictable and different of the another Enumerable methods.

Users will expect that symbol argument is converted in proc and then applied to object.

reduce (since v1.8.7) is older than public_send (since 1.9.1), maybe this is the reason of the reduce works like that.

But these days, as we have public_send and the :symbol.to_proc works similar to public_send I think make sense the reduce works with :symbol.to_proc, and not reaching private methods.

Hanmac (Hans Mackowiak) wrote:

reduce(&:+) is different from
reduce(:+), this one has nothing to do with :+.to_proc

reduce/inject with symbol param does call the method internally without checking if its private or not

Updated by Hanmac (Hans Mackowiak) over 2 years ago

i think you still mix reduce(&:+) with reduce(:+)
both are two totally different ways to call this method.
(the later doesn't go the way with a Proc object)

because reduce("+") works too

#8

Updated by nobu (Nobuyoshi Nakada) over 2 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r58871.


enum.c: respect method visibility

  • enum.c (ary_inject_op): should respect method visibility, do not optimize uncallable method. [ruby-core:81349] [Bug #13592]

Updated by usa (Usaku NAKAMURA) over 2 years ago

  • Backport changed from 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN to 2.2: WONTFIX, 2.3: WONTFIX, 2.4: UNKNOWN

memo: I think this is a bug, but it may cause some compatibility problems to change the behavior in teeny release, then I decided not to backport this to ruby_2_3.

Also available in: Atom PDF