I'm confused about Ruby.2.5.3 Method#arity for Dir.entries and Dir#entries

Method#arity:
Returns an indication of the number of arguments accepted by a method.
Returns a nonnegative integer for methods that take a fixed number of arguments.
For Ruby methods that take a variable number of arguments,
returns -n-1, where n is the number of required arguments. ...

In the following:
1. Why isn't MRI Dir.method(:entries).arity == 1?
2. Why isn't JRuby Dir.method(:entries).arity == -2?
3. Why isn't MRI d.method(:entries).arity == 0? (Where d = Dir.new(".").)

Thanks in advance for any help!

https://ruby-doc.org/core-2.5.3/Dir.html#method-c-entries
Public Class Methods
entries( dirname ) --> array
entries( dirname, encoding: enc ) --> array
Returns an array containing all of the filenames in the given directory.
Will raise a SystemCallError if the named directory doesn't exist.
The optional encoding keyword argument specifies the encoding of the directory.
If not specified, the filesystem encoding is used.

# OS= Microsoft Windows 7 Professional 64-bit

## MRI Ruby irb
RUBY_PLATFORM #=> "x64-mingw32"
RUBY_VERSION #=> "2.5.3"
String.method(:chomp) #=> undefined method 'chomp' for #<Class:String>
s = "str*" #=> "str*"
s.chomp() #=> "str*"
s.chomp("?") #=> "str*"
s.chomp("*") #=> "str"
s.chomp("*", 1) #=> wrong number of arguments (given 2, expected 0..1)
s.method(:length).arity #=> 0 # as expected: needs 0 arguments
s.method(:chomp).arity #=> -1 # as expected: needs 0 or 1 arguments
Encoding.find("filesystem") #=> #<Encoding:Windows-1252>
enc = Encoding::ASCII_8BIT #=> #<Encoding:ASCII-8BIT>
d = Dir.new(".") #=> #<Dir:.>
Dir.method(:entries).arity #=> -1 # implying n = 0 so can accept 0 arguments
d.method(:entries).arity #=> -1 # implying n = 0 so can accept 0 arguments
Dir.entries(".") #=> [ array of files in "." ]
Dir.entries(".", enc) #=> wrong number of arguments (given 2, expected 1)
Dir.entries() #=> wrong number of arguments (given 0, expected 1)
d.entries() #=> [ array of files in "." ]
d.entries(enc) #=> wrong number of arguments (given 1, expected 0)

## JRuby jirb
# essentially as for MRI Ruby except for:
RUBY_PLATFORM #=> "java"
RUBY_VERSION #=> "2.5.3"
Dir.method(:entries).arity #=> -1 # implying n = 0 so can accept 0 arguments
d.method(:entries).arity #=> 0 # implying n = 0 so must have 0 arguments
Dir.entries(".") #=> [ array of files in "." ]
Dir.entries(".", enc) #=> [ array of files in "." ]
Dir.entries(".", enc, 3) #=> wrong number of arguments (given 3, expected 1..2)
Dir.entries() #=> wrong number of arguments (given 0, expected 1..2)

Colin Bartlett wrote:

Method#arity: Returns an indication of the number of arguments accepted
by a method. Returns a nonnegative integer for methods that take a fixed
number of arguments. For Ruby methods that take a variable number of
arguments, returns -n-1, where n is the number of required arguments. ...

In the following: 1. Why isn't MRI Dir.method(:entries).arity == 1?

Dir.method(:entries).arity #=> -1 # implying n = 0 so can accept 0
Dir.entries() #=> wrong number of arguments (given 0, expected 1)

In the ... section of your quote from the docs: "[arity] For methods written
in C, returns -1 if the call takes a variable number of arguments."

Dir.entries is indeed written in C:

    dir_entries(int argc, VALUE *argv, VALUE io)

If I'm not too lost, it looks like:

    dir_entries
      -> dir_open_dir
        -> dir_s_open
          -> dir_initialize
            -> rb_scan_args

    rb_scan_args(argc, argv, "1:", &dirname, &opt);

"1:" 1 mandatory argument, keyword arguments

Looks like a couple of bugs to me.

···

El 7/10/19 a las 10:53, Colin Bartlett escribió:

Method#arity:
Returns an indication of the number of arguments accepted by a method.
Returns a nonnegative integer for methods that take a fixed number of arguments.
For Ruby methods that take a variable number of arguments,
returns -n-1, where n is the number of required arguments. ...

In the following:
1. Why isn't MRI Dir.method(:entries).arity == 1?
2. Why isn't JRuby Dir.method(:entries).arity == -2?
3. Why isn't MRI d.method(:entries).arity == 0? (Where d = Dir.new(".").)

Thanks in advance for any help!

Can you please explain to me what is going on sir with the program thank
you so much Danielle Lee Ramos

···

On Tue, Oct 22, 2019, 7:15 AM gga <ggarra13@gmail.com> wrote:

El 7/10/19 a las 10:53, Colin Bartlett escribió:
> Method#arity:
> Returns an indication of the number of arguments accepted by a method.
> Returns a nonnegative integer for methods that take a fixed number of
arguments.
> For Ruby methods that take a variable number of arguments,
> returns -n-1, where n is the number of required arguments. ...
>
> In the following:
> 1. Why isn't MRI Dir.method(:entries).arity == 1?
> 2. Why isn't JRuby Dir.method(:entries).arity == -2?
> 3. Why isn't MRI d.method(:entries).arity == 0? (Where d = Dir.new(".").)
>
> Thanks in advance for any help!
Looks like a couple of bugs to me.

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Thank you. I clearly didn't look closely enough at the whole Method#arity
description, which is:
https://ruby-doc.org/core-2.5.3/Method.html#method-i-arity
Method#arity:
Returns an indication of the number of arguments accepted by a method.
Returns a nonnegative integer for methods that take a fixed number of
arguments.
For Ruby methods that take a variable number of arguments,
returns -n-1, where n is the number of required arguments.
Keyword arguments will be considered as a single additional argument,
that argument being mandatory if any keyword argument is mandatory.
For methods written in C, returns -1 if the call takes a variable number of
arguments.

My apologies for my delay in responding: I'd sort of forgotten that I'd
asked this question, and ironically (?) I now can't remember why.

I think I was trying to write something that used a method (quite possibly
Dir.entries) which might differ between different Ruby versions, and
Method#arity was a kludgy way to find out (at least roughly) what arguments
the method took.

Anyway, thank you for your reply.

···

On Thu, Oct 17, 2019 at 3:37 AM Frank J. Cameron <fjc@fastmail.net> wrote:

...
In the ... section of your quote from the docs: "[arity] For methods
written
in C, returns -1 if the call takes a variable number of arguments."

Dir.entries is indeed written in C:
...

That was what I thought, which was one reason I posted my question.

But I think Frank J. Cameron's reply explains what's going on, so I now
don't think it's a bug: I assume there's a good reason why "For methods
written in C, returns -1 if the call takes a variable number of
arguments.For methods written in C, returns -1 if the call takes a variable
number of arguments".

There are still the questions of why are there some differences between how
Dir.entries behaves in Ruby and JRuby, and I'll think about that a bit more.

In my reply to Frank J. Cameron I said that I now can't recall why I asked
the question. I still can't recall it, but thinking about it a bit more it
looks like I might be able to get the sort of information I was after by
deliberately calling a method with zero arguments if it must have at least
one argument, or with definitely too many arguments if it can have zero
arguments, rescuing the exception, and then looking at the ArgumentError
message. For example:

Dir.entries() rescue v = $!
puts v.to_s() #=> "wrong number of arguments (given 0, expected 1)"

···

On Tue, Oct 22, 2019 at 1:15 PM gga <ggarra13@gmail.com> wrote:

...
Looks like a couple of bugs to me.

My apologies for my delay on responding. I hope the following helps, and
isn't too little explanation. Or too much! (I don't know how much
experience you have with Ruby.)

I ran Interactive Ruby (irb) and JRuby Interactive Ruby (jirb) as a simple
way of demonstrating what I was asking.
I use comments like "#=> ..." to show the result of a command.
The results shown below are for "Microsoft Windows" Ruby irb;I also show
the results for JRuby jirb if that is different

For more information on the method calls I made:
* String#chomp: https://ruby-doc.org/core-2.5.3/String.html#method-i-chomp
* String#length:
https://ruby-doc.org/core-2.5.3/String.html#method-i-length
* Dir.entries: https://ruby-doc.org/core-2.5.3/Dir.html#method-c-entries
* Dir#entries: I couldn't find documentation for this Public Instance
Method;
                  I don't know why not.
* Encoding: https://ruby-doc.org/core-2.5.3/Encoding.html

# First I give information about the Ruby version I'm using:
RUBY_PLATFORM #=> "x64-mingw32" #JRuby #=> "java"
RUBY_VERSION #=> "2.5.3"

# Next I chose a Ruby method to show how I think Method#arity works;
# I decided to use String#chomp.
# First I show how it behaves with different numbers of arguments,
# then I show the (actual - and expected!) result of s.method(:chomp).arity,
# and also of s.method(:length).arity because I know String#length has
arity 0.

···

On Wed, Oct 23, 2019 at 8:03 AM Danielle Velie <veliedanielle33@gmail.com> wrote:

Can you please explain to me what is going on sir with the program thank
you so much Danielle Lee Ramos

#
# I also show that to get the arity of a method of an object of a class
# we need to call method(:method_name).arity on the object, not the class.
# I did that because as well as Dir objects having an instance method
"entries"
# the Dir class itself has a singleton method also called "entries",
# and I wanted to ensure I knew which method I was getting the arity for.

String.method(:chomp) #=> undefined method 'chomp' for #<Class:String>
s = "str*" #=> "str*"
s.chomp() #=> "str*"
s.chomp("?") #=> "str*"
s.chomp("*") #=> "str"
s.chomp("*", 1) #=> wrong number of arguments (given 2, expected 0..1)
s.method(:length).arity #=> 0 # as expected: needs 0 arguments
s.method(:chomp).arity #=> -1 # as expected: needs 0 or 1 arguments

# I had found that in JRuby 2.5.3 Dir.entries could have an optional
argument
# of the string Encoding to be used, but that this was not the case
# for my Ruby 2.5.3. So I set up an Encoding object.
Encoding.find("filesystem") #=> #<Encoding:Windows-1252>
enc = Encoding::ASCII_8BIT #=> #<Encoding:ASCII-8BIT>

# Now I call both the instance method "entries" of Dir objects,
# and the singleton method "entries" of the Dir class,
# showing the results of different combinations of arguments,
# and the results of finding the arity of those "entries" methods.
# These also show where the behaviour of Ruby and JRuby differ.
d = Dir.new(".") #=> #<Dir:.>
Dir.method(:entries).arity #=> -1 # implying n = 0 so can accept 0
arguments
d.method(:entries).arity #=> -1 # implying n = 0 so can accept 0
arguments
d.method(:entries).arity #JRuby #=> 0 # implying n = 0 so must have 0
arguments
Dir.entries(".") #=> [ array of files in "." ]
Dir.entries(".", enc) #=> wrong number of arguments (given 2, expected 1)
                         #JRuby #=> [ array of files in "." ]
Dir.entries(".", enc, 3) #=> wrong number of arguments (given 3, expected 1)
                  #JRuby #=> wrong number of arguments (given 3, expected
1..2)
Dir.entries() #=> wrong number of arguments (given 0, expected 1)
                  #JRuby #=> wrong number of arguments (given 0, expected
1..2)
d.entries() #=> [ array of files in "." ]
d.entries(enc) #=> wrong number of arguments (given 1, expected 0)