On Thursday 07 January 2010, Thom Wharton wrote:
|Is this info still valid? More specifically, would I have to create a
|new method for my class to have it return nil?
Yes, it’s still valid. Class.new, which is the method you actually
invoke when
you write MyCls.new, always returns the new instance, regardless of the
value
returned by initialize (if it were not so, every initialize method
should
explicitly return self to have new return the new instance).
|And would my class
|initializer method have to raise an exception or could it return nil if
|the construction fails?
If you override new, you can have it treat the value returned by
initialize
how you want. There’s nothing special in the initialize method (aside
from the
fact that it’s always private). If you want, you can decide that your
initialize method will return nil if it failed and anything else if it
succeeds. Or it may return 5 if it fails and 2 if it succeeds. Then in
the new
method you check by the return value of initialize and proceed
accordingly.
|Btw, I’ve noticed that the File class will return nil if you call the
|new method with a filename that doesnt refer to an existing file. Does
|the File class have its own new/initialize methods? If so, is that code
|available online for examination?
It does, but they’re written in C, so you’ll have to understand a bit of
ruby
C api to understand them. You can download the ruby source from
www.ruby-lang.org. The initialize method is implemented in
rb_file_initialize
C function while I think (but I’m not sure) that the new method is
implemented
in rb_io_s_new. Both functions are defined in io.c.
However, implementing a new method is truly quite easy:
class MyClass
def self.new *args
inst = allocate
res = inst.send :initialize, *args
if res < 5 then “Hello”
else res
end
end
def initialize x
x
end
end
i1 = MyClass.new 3
p i1
i2 = MyClass.new 6
p i2
MyClass.new returns the new instance if the initialize method returns a
number
greater than 4 and the string “Hello” if initialize returns a number up
to
four.
I hope this helps
Stefano