[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

ruby constructor return value?

Brendan Stennett

4/2/2008 9:08:00 PM

How do I alert an error if it occurs in an object's constructor?

Example:
Say im creating an object that relies on a give record from the database
zipcodes.

In php...
<?php
class Zip {
private $zipcode;
function __construct(zipcode) {
//..code the looks up zipcode
$numOfRecords = $mysqli->affected_rows;
if ($numOfRecords == 0) {
//this takes advantage of dynamically typed languages and passes a
boolean
//value instead of the newly created object to the variables thats
being
//assigned
return false;
} else {
$this->zipcode = zipcode;
}
}
}

//then...
if ($o = new Zip('90210')) {
//code if zipcode exists
} else {
//code if it doesn't
}
?>

In ruby..
class Zip
def initialize(zipcode)
o = Zipcode.find_by_zipcode(zipcode)
if o.length == 0
return false
else
@zipcode = zipcode
end
end
end

//then...
if o = Zip.new('00000')
//this block execute whether or not that zip code exists
else
//never happens
end

..now i know there are easier ways to do this, but its just an example
to illustrate my point.
--
Posted via http://www.ruby-....

7 Answers

Lyle Johnson

4/2/2008 9:18:00 PM

0

On Wed, Apr 2, 2008 at 4:08 PM, Brendan Stennett <brendan6@gmail.com> wrote:

> How do I alert an error if it occurs in an object's constructor?

Raise an exception.

class Zip
def initialize(zipcode)
o = Zipcode.find_by_zipcode(zipcode)
if o.length == 0
raise ArgumentError, "no zip code specified"
else
@zipcode = zipcode
end
end
end

begin
o = Zip.new('00000')
rescue ArgumentError
# deal with the error here
end

Hope this helps,

Lyle

Brendan Stennett

4/2/2008 10:38:00 PM

0

>
> begin
> o = Zip.new('00000')
> rescue ArgumentError
> # deal with the error here
> end

I was reading up on exception handling..but i dont understand that
difference between throw/catch blocks and begin/resuce blocks. My 2
backgrounds (PHP and VB.NET) both seem to have similar structures in
Ruby. PHP had try/throw/catch blocks while ruby has throw/catch and
VB.NET has try/catch/finally while Ruby has begin/rescue/ensure.
--
Posted via http://www.ruby-....

Tim Hunter

4/2/2008 10:46:00 PM

0

Brendan Stennett wrote:
>> begin
>> o = Zip.new('00000')
>> rescue ArgumentError
>> # deal with the error here
>> end
>
> I was reading up on exception handling..but i dont understand that
> difference between throw/catch blocks and begin/resuce blocks. My 2
> backgrounds (PHP and VB.NET) both seem to have similar structures in
> Ruby. PHP had try/throw/catch blocks while ruby has throw/catch and
> VB.NET has try/catch/finally while Ruby has begin/rescue/ensure.

begin/rescue is for handling exceptions. throw/catch is for jumping out
of a deeply nested construct during normal processing.

--
RMagick: http://rmagick.ruby...
RMagick 2: http://rmagick.ruby...rmagick2.html

Thomas Hurst

4/2/2008 11:29:00 PM

0

* Brendan Stennett (brendan6@gmail.com) wrote:

> if o = Zip.new('00000')
> //this block execute whether or not that zip code exists
> else
> //never happens
> end

Normally you'd use an exception; e.g. make a ZipCodeNotFound class
inherited from StandardError and rescue it. You could even do:

o = Zip.new(..) rescue nil

And this will rescue the exception and return nil. It will also eat any
other StandardError, so beware. If you want users of the class to be
able to just check for nil/false, make a factory method:

class Zip
def self.find(zip)
new(zip)
rescue ZipCodeNotFound
false
end
end

o = Zip.find('..')

However, new is just a method like any other; you can override it if you
really want it to potentially return nil:

class Zip
def self.new(*args)
o = allocate
if o.__send__(:initialize, *args)
return o
else
return nil
end
end
end

Allocate will make a new object without calling the constructor, you can
then call initialize yourself (using __send__ as it's a private method)
and conditionally return your new object.

Since this may be surprising behavior for .new I don't really recommend
it, though.

--
Thomas 'Freaky' Hurst
http...

Brendan Stennett

4/3/2008 5:08:00 AM

0

> Normally you'd use an exception; e.g. make a ZipCodeNotFound class
> inherited from StandardError and rescue it. You could even do:


Now...is it better to make a new exception for each type of error that
could happen or just use some standard exception (or general exception
that inherits StandardError that i could make) and change the error
message?
--
Posted via http://www.ruby-....

Paul McMahon

4/3/2008 5:31:00 AM

0

Brendan Stennett wrote:
>
> In ruby..
> class Zip
> def initialize(zipcode)
> o = Zipcode.find_by_zipcode(zipcode)
> if o.length == 0
> return false
> else
> @zipcode = zipcode
> end
> end
> end
>
> //then...
> if o = Zip.new('00000')
> //this block execute whether or not that zip code exists
> else
> //never happens
> end
>
> ..now i know there are easier ways to do this, but its just an example
> to illustrate my point.

Maybe I'm missing something, but why not just push the creation into
Zipcode. I can't see why you would want to do this check in the
constructor itself...

class Zipcode
def self.find_by_zipcode(zipcode)
zipcode = ... # query db
if zipcode.length == 0
nil
else
Zip.new(zipcode)
end
end
end

class Zip
def initialize(zipcode)
@zipcode = zipcode
end
end

//then...
if o = Zip.find_by_zipcode('00000')
// zipcode exists
else
// doesn't exist
end

Brendan Stennett

4/3/2008 5:38:00 AM

0

Hmm....well im not used to using Models so i didn't really think about
attacking it that way...i dont see why i couldnt though. I'm going to
play around with that...see how it goes
--
Posted via http://www.ruby-....