From: Alex Young Date: 2007-05-27T17:12:26+09:00 Subject: Re: Can an initialize method fail? Peter Seebach wrote: > I may be doing this wrong. :) In some languages, I > might do something like: > user = User.new(name, password) > > If the User class is unable to initialize a corresponding > user, it might not produce a valid User object. > > What is a good way to do something like this? It seems that I could > do it by having User#initialize throw an exception, but my intuition > is that "user got password wrong" is not exactly an exceptional circumstance; > I have been told exceptions should be used only for unusual cases, and > should not be part of the fairly normal usage of a program. > > My assumption that a "User" should be one who is logged in may not > be strictly necessary, but I rather like the way it simplifies everything > else -- this way, only one or two lines of code ever have to consider > the possibility of a user who didn't authenticate successfully. > > So far as I can tell, though, the initialize method's return is > politely ignored. I'd use a different class method, like User.login, or some such. Then you can return either a valid User instance or nil as required. If you want to completely avoid exceptions, you'll either need to have a #valid? method in the instance, or actually do the credential validation at the class level (which seems slightly wrong to me, but there you go). It might look a little like this: class User def User.login(name, password) u = User.new(name, password) return u.valid? ? u : nil end end or: class User def User.login(name, password) can_log_in_with(name, password) ? User.new(name) : nil end def User.can_log_in_with(name, password) # do the name and password validation outside a User object here end end Of course, if you do go this route, you'll need to make sure that you never call User.new directly, and popping an exception under those circumstances is, I think, justified. -- Alex