What’s the best way of checking if an argument has been given or not?
That is, what’s the best way of achieving
class A
ArgumentMissing = Object.new.freeze
def b(c = ArgumentMissing)
if ArgumentMissing.equal? c
puts 'no argument was given'
else
puts c
end
end
end
A.new.b # => no argument was given
A.new.b 1 # => 1
? I remember seeing something that didn’t require a constant like
this, but I can’t seem to find it. (Note: I don’t want to use nil for
this particular case. I would preferably use a value that is
inaccessible outside of A.)
Your suggestion is valid. though it seems I underspecified my question
in yet another way. Until Ruby gets a rb_scan_args equivalent, I’d
rather not complicate my argument processing unnecessarily by
destructuring an argument array by hand.
···
On Fri, Oct 14, 2011 at 15:29, Bartosz Dziewoński <matma.rex@gmail.com> wrote:
You can use this syntax, too. "args" becomes an array of all arguments given.
def foo *args
if args.length==0
puts 'no argument was given'
else
puts args[0]
end
end
If you only allow one argument, you should do some checking whether
there are too many.
Hmm, if you really don't want to use the splat *args, you could create a
new instance of A and extend it with a #missing? method, and pass that
instance as the default value for the method. That way, the instance
won't be available across classes and you can just check if the argument
responds_to :missing?
class A
missing_arg = new
class << missing_arg
def missing?
true
end
end
That's pretty cleaver, although it reads perhaps a bit too strangely.
What I have always done is.... obviously, if `nil` is not a valid
argument, then just use that.
def b(a=nil)
if a
...
end
But if `nil` is valid then use `ArgumentError`, as that won't be a
valid argument in 99.99% (or so) cases anyway.
def b(a=ArgumentError)
if a == ArgumentError
...
end
For the most robust solution, Ruby Facets defines a toplevel constant
called `NA`, the sole purpose of which is to fill in for cases such as
this.
def b(a=NA)
if a == NA
...
end
That's my favorite, but it require's a dependency on Facets or copy
and pasting the extra code to one's project.
(hmm... it occurs to me that global `$NA` variable would be good to
have too so there's no namespace issues such as in a BasicObjcet
subclass)
···
On Oct 14, 11:31 am, Jens Wille <jens.wi...@uni-koeln.de> wrote:
luke gruber [2011-10-14 17:15]:> That way, the instance won't be available across classes and you
> can just check if the argument responds_to :missing?
or you can just do this:
class A
def b(c = d = true) # or some other truthy value
if d
puts 'no argument was given'
else
puts c
end
end
end
can't remember where i first saw it, but it works perfectly
The downside to this approach is that you use "true" to say
something is "false".
well, i guess that depends on your point of view you seem to read
it as "argument given? => false"; i read it as "apply default case?
=> true". which is why i always name that variable 'default' to
begin with.