Defining a method with an argument with a default value

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 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

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

On 7/25/06, Dr Nic [email protected] 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… :slight_smile:

Thanks,

Pedro.

On 7/25/06, Daniel S. [email protected] 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.

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. :slight_smile:

Must free myself of silly mental restrictions brought over from lesser
languages… :slight_smile:

If you’re feeling really lazy or just want to test something in IRB
before posting on a forum :slight_smile: 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 :slight_smile:

[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!

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
}

Daniel DeLorme wrote:

=> 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 :slight_smile:

Cheers,
Daniel

Daniel S. 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

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