Check if any arguments have passed

Here is the 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 arguments without arguments and one argument nil ?

UPD

I decided to add a usage example in javascript to make things clearer:

 someProp: function(value) { if (arguments.length) { this._someProp = value; } return this._someProp; } 
+6
source share
2 answers

In general, there are three ways. One way is to use the default value to set another variable indicating whether the default value has been 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 kind of object that is known only inside the method as the default value, so the outsider cannot pass this object to:

 -> { 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 of them is more idiomatic. The second (in fact, its variant) is used inside Rubinius, but I have never met it anywhere.

A third solution would be to take a variable number of arguments using 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 a re-implementation of Ruby authentication manually. (And we still do not understand, because it raises an exception inside the method, while Ruby raises it at the call site.) It also requires that you manually document your method signature, because automatic documentation generators like RDoc or YARD will cause an arbitrary number of parameters instead of one optional.

+10
source

You can request splat arguments:

 def f(*args) if args.empty? puts 'no parameters passed' else p1 = args[0] ... end end 

Another option might be to have a private object to indicate if any parameter passed:

 def initialize @no_param_passed = Object.new end def f(p1 = @no_param_passed) if p1 == @no_param_passed puts 'no parameters passed' end end 
+5
source

Source: https://habr.com/ru/post/969592/


All Articles