Defining a method with an argument with a default value

Discussion in 'Ruby' started by Pedro Côrte-Real, Jul 25, 2006.

  1. I have this line in a class method to define an initializer:

    define_method:)initialize){|value| @value = value}

    But I want something more like this:

    define_method:)initialize){|value=nil| @value = value if value}

    which doesn't seem to be possible because of the "value=nil" part. Is
    there some way to do this that isn't eval? Eval would work fine since
    this is pretty static code and I have unit tests for it but I try to
    avoid it if I can. I've only used it before for performance to turn
    some code with runtime tests into eval-time tests.

    Pedro.
    Pedro Côrte-Real, Jul 25, 2006
    #1
    1. Advertising

  2. Pedro Côrte-Real wrote:
    > I have this line in a class method to define an initializer:
    >
    > define_method:)initialize){|value| @value = value}
    >
    > But I want something more like this:
    >
    > define_method:)initialize){|value=nil| @value = value if value}


    First of all, you don't need the `if value' part -- when Ruby sees
    @value, it is immediately created, with the value nil, so there's no
    problem with giving it the value nil explicitly. Second, I believe you
    can just do this:

    define_method:)initialize){|value| @value = value}

    If #initialize is called with no arguments, `value' will just be nil,
    although IRB may issue a warning.


    Cheers,
    Daniel
    Daniel Schierbeck, Jul 25, 2006
    #2
    1. Advertising

  3. Pedro Côrte-Real

    Dr Nic Guest

    You could do the following:

    Foo.class_eval do
    def bar(tar=0)
    tar * 2
    end
    end

    Foo.new.tar
    => 0
    Foo.new.tar 4
    => 8

    --
    Posted via http://www.ruby-forum.com/.
    Dr Nic, Jul 25, 2006
    #3
  4. On 7/25/06, Daniel Schierbeck <> wrote:
    > First of all, you don't need the `if value' part -- when Ruby sees
    > @value, it is immediately created, with the value nil, so there's no
    > problem with giving it the value nil explicitly.


    Yes, I knew that.

    > Second, I believe you
    > can just do this:
    >
    > define_method:)initialize){|value| @value = value}
    > If #initialize is called with no arguments, `value' will just be nil,
    > although IRB may issue a warning.



    That's what I have but it throws a warning and I wanted to shut it up.
    Guess I'll have to do the eval.

    Thanks,

    Pedro.
    Pedro Côrte-Real, Jul 25, 2006
    #4
  5. On 7/25/06, Dr Nic <> wrote:
    > You could do the following:
    >
    > Foo.class_eval do
    > def bar(tar=0)
    > tar * 2
    > end
    > end


    Yep, this works great, thanks. It's an eval but it's the one with a
    block instead of a string. Didn't know "def" worked inside a block.
    Must free myself of silly mental restrictions brought over from lesser
    languages... :)

    Thanks,

    Pedro.
    Pedro Côrte-Real, Jul 25, 2006
    #5
  6. Pedro Côrte-Real

    Dr Nic Guest

    > Must free myself of silly mental restrictions brought over from lesser
    > languages... :)


    If you're feeling really lazy or just want to test something in IRB
    before posting on a forum :) then this is what you might type:

    Foo.class_eval { def bar(tar=0); tar * 2; end}

    Of course then you should reformat it for the forum :)

    --
    Posted via http://www.ruby-forum.com/.
    Dr Nic, Jul 25, 2006
    #6
  7. Pedro Côrte-Real

    Dr Nic Guest

    Oooh. And another cool use of class_eval is:

    >> code = %q{

    def bar(tar=0)
    tar * 2
    end
    }
    => " def bar(tar=0)\n tar * 2\nend"
    >> Foo.class_eval code

    => nil
    Foo.new.bar 10
    => 20

    So, this means you can take the text to eval against the class from
    anywhere. :)

    --
    Posted via http://www.ruby-forum.com/.
    Dr Nic, Jul 25, 2006
    #7
  8. Pedro Côrte-Real

    Guest

    Hi,

    At Tue, 25 Jul 2006 19:33:38 +0900,
    =?ISO-8859-1?Q?Pedro_C=F4rte-Real?= wrote in [ruby-talk:203711]:
    > define_method:)initialize){|value=nil| @value = value if value}


    define_method:)initialize) {|*values|
    case values.size
    when 0
    value = nil
    when 1
    value = values.first
    else
    raise ArgumentError, "wrong number of arguments (#{values.size} for 0)"
    end
    @value = value
    }

    --
    Nobu Nakada
    , Jul 25, 2006
    #8
  9. Pedro Côrte-Real

    Dr Nic Guest

    [Warning: Anal retentive refactoring ahead]

    define_method:)initialize) do |*values|
    case values.size
    when 0..1
    @value = values.first
    else
    raise ArgumentError, "wrong number of arguments (#{values.size} for
    0)"
    end
    end

    or perhaps

    define_method:)initialize) do |*values|
    @value = values.shift
    unless @value.length == 0
    raise ArgumentError, "wrong number of arguments (#{values.size} for
    0)"
    end
    end

    Too... many... options... ahh!

    --
    Posted via http://www.ruby-forum.com/.
    Dr Nic, Jul 25, 2006
    #9
  10. Daniel Schierbeck wrote:
    > First of all, you don't need the `if value' part -- when Ruby sees
    > @value, it is immediately created, with the value nil


    Sorry for being pedantic but this is not quite true (although in this
    case it doesn't make a difference):

    irb(main):001:0> @a = 1 if false
    => nil
    irb(main):002:0> b = 2 if false
    => nil
    irb(main):003:0> @c = nil
    => nil
    irb(main):004:0> defined? @a
    => nil
    irb(main):005:0> defined? b
    => "local-variable"
    irb(main):006:0> defined? @c
    => "instance-variable"


    Daniel
    Daniel DeLorme, Jul 25, 2006
    #10
  11. Daniel DeLorme wrote:
    > Daniel Schierbeck wrote:
    >> First of all, you don't need the `if value' part -- when Ruby sees
    >> @value, it is immediately created, with the value nil

    >
    > Sorry for being pedantic but this is not quite true (although in this
    > case it doesn't make a difference):
    >
    > irb(main):001:0> @a = 1 if false
    > => nil
    > irb(main):002:0> b = 2 if false
    > => nil
    > irb(main):003:0> @c = nil
    > => nil
    > irb(main):004:0> defined? @a
    > => nil
    > irb(main):005:0> defined? b
    > => "local-variable"
    > irb(main):006:0> defined? @c
    > => "instance-variable"


    I know, but I was trying to simplify the problem :)


    Cheers,
    Daniel
    Daniel Schierbeck, Jul 25, 2006
    #11
  12. As long as we're throwing around options...
    > define_method:)initialize) do |*values|
    > @value = values.shift
    > unless @value.length == 0
    > raise ArgumentError, "wrong number of arguments (#{values.size} for
    > 0)"
    > end
    > end
    >

    define_method:)initialize) do |*values|
    raise ArgumentError, "wrong number of arguments (#{values.size} for 0)" if values.length > 1
    @value = values.first
    end

    Cheers!
    Patrick
    Patrick Ritchie, Jul 25, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. johny smith
    Replies:
    8
    Views:
    400
    Peter Koch Larsen
    Jul 2, 2004
  2. LaundroMat
    Replies:
    50
    Views:
    938
    Hendrik van Rooyen
    Oct 14, 2006
  3. Sam
    Replies:
    3
    Views:
    235
    Gerard Flanagan
    Mar 10, 2008
  4. david.karr
    Replies:
    21
    Views:
    877
    Arne Vajhøj
    Mar 14, 2010
  5. ernest

    default argument in method

    ernest, Dec 12, 2010, in forum: Python
    Replies:
    9
    Views:
    255
    DevPlayer
    Jan 1, 2011
Loading...

Share This Page