[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Defining a method with an argument with a default value

Pedro Côrte-Real

7/25/2006 10:34:00 AM

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.

11 Answers

Daniel Schierbeck

7/25/2006 11:07:00 AM

0

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

Dr Nic

7/25/2006 11:15:00 AM

0

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

Pedro Côrte-Real

7/25/2006 11:18:00 AM

0

On 7/25/06, Daniel Schierbeck <daniel.schierbeck@gmail.com> 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

7/25/2006 11:21:00 AM

0

On 7/25/06, Dr Nic <drnicwilliams@gmail.com> 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.

Dr Nic

7/25/2006 11:29:00 AM

0

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

Dr Nic

7/25/2006 11:32:00 AM

0

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

Nobuyoshi Nakada

7/25/2006 11:46:00 AM

0

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

Dr Nic

7/25/2006 12:08:00 PM

0

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

Daniel DeLorme

7/25/2006 2:26:00 PM

0

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 Schierbeck

7/25/2006 7:56:00 PM

0

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