Forum: Ruby Detecting default used in method calls

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
E27dbbc379290cb930648a817577520c?d=identicon&s=25 Peter Lynch (thereader)
on 2007-01-02 16:30
I would like to know if a function has been called with or without an
optional argument.

If I have -

 def the_Function (a, b = '')
 end

and I invoke it like this -

 the_Function('a')
 the_Function('a', '')

is there any way for me to tell within the_Function which form of
invocation was used?
Fc784eadb3b54531fdc3d2053db6f83f?d=identicon&s=25 Mat Schaffer (Guest)
on 2007-01-02 17:06
(Received via mailing list)
On Jan 2, 2007, at 10:31 AM, Peter Lynch wrote:

>  the_Function('a')
>  the_Function('a', '')
>
> is there any way for me to tell within the_Function which form of
> invocation was used?

Not sure if there's something more graceful, but my first instinct
would be to define it like

def the_function(*args)
   ...
end

Then the function could contain the defaulting logic in the event of
only one element in the args array.
-Mat
E0ed615bd6632dd23165e045e3c1df09?d=identicon&s=25 Florian Gross (Guest)
on 2007-01-02 17:22
(Received via mailing list)
Peter Lynch wrote:

> I would like to know if a function has been called with or without an
> optional argument.

Not very pretty:

def fun(a, b = (no_b = true; 5))
   if no_b then
     "Fun(%p): %p" % [a, b]
   else
     "Fun(%p, %p)" % [a, b]
   end
end

fun(1) # => "Fun(1): 5"
fun(1, 2) # => "Fun(1, 2)"
852a62a28f1de229dc861ce903b07a60?d=identicon&s=25 Gavin Kistner (phrogz)
on 2007-01-02 17:36
(Received via mailing list)
Peter Lynch wrote:
> I would like to know if a function has been called with or without an
> optional argument.

def foo( a, b=nil )
  if b.nil?
    # whoa
    b=''
  end
  # ...
end
6d3c187a8b3ef53b08e3e7e8572c4fea?d=identicon&s=25 Jeremy McAnally (Guest)
on 2007-01-02 17:40
(Received via mailing list)
def myfunction(a, b = nil)
  if (b):
    puts "There's a B!"
  else
    puts "Business as usual..."
  end
end

If you have more than one argument, then do something like this...

def myfunction(args={})

a = args[:a] || 'my default A'

b = args[:b] || 'my default B'

# and so on...
end

myfunction(:a => 'b', :b => 'c')

You can do this with merge too (i.e., build a hash with the keys A, B,
and so on, and then merge it with the argument).

I think there's a more graceful way to do this, but I'm too tired to
find it! :(

--Jeremy

On 1/2/07, Peter Lynch <argnosis@yahoo.com.au> wrote:
>  the_Function('a')
>  the_Function('a', '')
>
> is there any way for me to tell within the_Function which form of
> invocation was used?
>
> --
> Posted via http://www.ruby-forum.com/.
>
>


--
My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-02 18:00
(Received via mailing list)
On 02.01.2007 17:20, Florian Gross wrote:
> Peter Lynch wrote:
>
>> I would like to know if a function has been called with or without an
>> optional argument.
>
> Not very pretty:

But clever!

> def fun(a, b = (no_b = true; 5))
>   if no_b then
>     "Fun(%p): %p" % [a, b]
>   else
>     "Fun(%p, %p)" % [a, b]
>   end
> end
>
> fun(1) # => "Fun(1): 5"
> fun(1, 2) # => "Fun(1, 2)"

The only other reasonable alternative I can see is this:

def fun(a,*bb)
   if bb.empty?
     puts "no b"
   else
     puts "b=#{b}"
   end
end

Note that the other approach that has been mentioned cannot reliably
detect whether the parameter was set or not:

def fun(a,b=nil)
   if b.nil?
     puts "no b"
   else
     puts "b=#{b}"
   end
end

irb(main):013:0> fun 1
no b
=> nil
irb(main):014:0> fun 1,2
b=2
=> nil
irb(main):015:0> fun 1,nil
no b
=> nil

(The last one should have printed "b=".)

You get more options if you want to use named parameters (i.e. a Hash):

def fun(args={})
   a = args[:a]
   b = args[:b]

   if args.has_key? :b
     puts "b=#{b}"
   else
     puts "no b"
   end
end

irb(main):053:0> fun(:a=>1)
no b
=> nil
irb(main):054:0> fun(:a=>1, :b=>2)
b=2
=> nil
irb(main):055:0> fun(:b=>2)
b=2
=> nil

Kind regards

	robert
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2007-01-02 20:37
(Received via mailing list)
On Jan 2, 2007, at 07:31, Peter Lynch wrote:

>  the_Function('a')
>  the_Function('a', '')
>
> is there any way for me to tell within the_Function which form of
> invocation was used?

No need to do those complicated things that everybody else is
trying.  Instead use an object that nobody else will pass you as a
sentinel:

class X

   SENTINEL = Object.new

   def the_function(a, b = SENTINEL)
     if b == SENTINEL then
       ...
     end
   end

end

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!



--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!



--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-01-02 20:51
(Received via mailing list)
On Wed, 3 Jan 2007, Peter Lynch wrote:

> the_Function('a')
> the_Function('a', '')
>
> is there any way for me to tell within the_Function which form of
> invocation was used?

   def the_function *a, &b
     case a.size
       when 0
         p 'zero args'
       when 1
         p 'one arg'
       when 2
         p 'two args'
       else
         raise ArgumentError
     end

     # ...
   end


but methods like this are often confusing to read

   the_function 'arg'

   the_function 'arg', 'wtf does this do?'

it's often better and more rubyish to use options

   def the_function arg, opts = {}, &block
     b = opts['b'] || opts[:b]
     # ....
   end


regards.


-a
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-02 21:09
(Received via mailing list)
Eric Hodel wrote:
>        ...
>      end
>    end
>
> end

You don't need to create your own, Exception works quite well:

 class X

    def the_function(a, b = Exception)
      if b == Exception then
        ...
      end
    end

 end

T.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-02 21:18
(Received via mailing list)
Florian Gross wrote:
> fun(1) # => "Fun(1): 5"
> fun(1, 2) # => "Fun(1, 2)"

Huh... That's pretty cool. Maybe prettier is we reduce it even more?

 def fun(a, b = (_b = 5))
    if _b then
      "Fun(%p): %p" % [a, b]
    else
      "Fun(%p, %p)" % [a, b]
    end
 end

 fun(1) # => "Fun(1): 5"
 fun(1, 2) # => "Fun(1, 2)"

Think that works as long as b doesn't need to default to nil or false.

Oh... and I'm sitting here pronouncing _b as "un-b".

T.
This topic is locked and can not be replied to.