Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if no arguments passed

Tags:

arguments

ruby

Here's some code:

$ cat 1.rb
#!/usr/bin/env ruby
def f p1 = nil
    unless p1   # TODO
        puts 'no parameters passed'
    end
end
f
f nil
$ ./1.rb
no parameters passed
no parameters passed

The question is, is there a way to distinguish between no arguments and one nil argument passed?

UPD

I decided to add a use case in javascript to make things hopefully clearer:

someProp: function(value) {
    if (arguments.length) {
        this._someProp = value;
    }
    return this._someProp;
}
like image 301
x-yuri Avatar asked May 20 '14 17:05

x-yuri


People also ask

How do you check if no argument is passed in C?

You can test it this way: int main(int argc, char *argv[]) { if (argc < 2) { printf("error: missing command line arguments\n"); return 1; } ... }

How do you check for no arguments in python?

Running this code in Pytest gives an error def two_fer(name=None): if name == 'Alice' or name == 'Bob': return ('One for ' + str(name) + ", one for me.") elif name == False: return ('One for you, one for me. ')

How do you read no of arguments passed to the script?

You can get the number of arguments from the special parameter $# . Value of 0 means "no arguments". $# is read-only. When used in conjunction with shift for argument processing, the special parameter $# is decremented each time Bash Builtin shift is executed.


1 Answers

There are three ways in general use. One way is to use the default value to set another variable indicating whether or not the default value was evaluated:

def f(p1 = (no_argument_passed = true; nil))
  'no arguments passed' if no_argument_passed
end

f      # => 'no arguments passed'
f(nil) # => nil

The second way is to use some object that is only known inside the method as default value, so that it is impossible for an outsider to pass that object in:

-> {
  undefined = BasicObject.new
  define_method(:f) do |p1 = undefined|
    'no arguments passed' if undefined.equal?(p1)
  end
}.()

f      # => 'no arguments passed'
f(nil) # => nil

Of these two, the first one is more idiomatic. The second one (actually, a variation of it) is used inside Rubinius, but I have never encountered it anywhere else.

A third solution would be to take a variable number of arguments using a splat:

def f(*ps)
  num_args = ps.size
  raise ArgumentError, "wrong number of arguments (#{num_args} for 0..1)" if num_args > 1
  'no arguments passed' if num_args.zero?
end

f      # => 'no arguments passed'
f(nil) # => nil

Note that this requires you to re-implement Ruby's arity checking by hand. (And we still haven't gotten it right, because this raises the exception inside the method, whereas Ruby would raise it at the call site.) It also requires you to manually document your method signature because automated documentation generators such as RDoc or YARD will infer an arbitrary number of parameters instead of a single optional one.

like image 175
Jörg W Mittag Avatar answered Oct 01 '22 20:10

Jörg W Mittag