From: Robert Klemme Date: 2004-02-20T20:20:29+09:00 Subject: Re: proposal: let kind_of take more arguments "Simon Strandgaard" schrieb im Newsbeitrag news:pan.2004.02.19.14.51.57.777201@adslhome.dk... > On Thu, 19 Feb 2004 15:43:05 +0100, Robert Klemme wrote: > > "Simon Strandgaard" schrieb im Newsbeitrag > >> > >> def push(choice) > >> if choice.kind_of?(Zero) == false and choice.kind_of?(One) == false > > > > Never compare boolean values to get boolean values. This can lead to > > hideous bugs if the method at hand does not return "true" or "false" - > > especially with languages that have more than one value for either. > > Thanks for the warning. I have actually had a few problems with it > earlier, without realizing this. :-)) I forgot to mention, that it's totally superfluous, too, and thus may cost you some machine cycles... :-)) > >> def push(choice) > >> unless choice.kind_of?(Zero, One) > >> raise "got #{choice.class}" > > > > ArgumentError is a good choice here. :-) > > I don't have full overview over Ruby's exception hierarchy, but yes > I should use this one here (which I do now). ;-) :-)) > >> end > >> @choices << choice > >> end > > > > Why don't you just do > > > > def push(choice) > > case choice > > when Zero, One > > @choices << choice > > else > > raise ArgumentError, "got #{choice.class}" > > end > > end > > a switch statement.. easier to read. > However I like to do bailout as soon as possible, > raising ArgumentError this late may make confusion. What do you mean by "late"? Do you mean that the line with "raise" stands below the actual operation. Didn't think of that, but yes, it might be confusing. OTOH, if you can read "case" then it's not so difficult, is it? > > > or > > > > def push(choice) > > raise ArgumentError, "got #{choice.class}" unless [Zero, > > One].map{|cl|choice.kind_of? cl}.any? > > @choices << choice > > end > > Confusion :-) http://lyricsheaven.topcities.com/survey_d_k_bestanden/ELO.htm#confusion > > def Object#kind_of_any?( *classes ) > > Yes thought of this.. which maked me propose this idea. I'm wondering though whether it's worth the effort. When using duck typing, you don't need kind_of? anyway. Btw, I had another idea: PUSH_ALLOWED = {Zero, One} def push(choice) raise ArgumentError, "got #{choice.class}" unless PUSH_ALLOWED[choice.class] @choices << choice end Of course there is a subtle difference since this does not take sub classes into consideration. But other than that, it should be faster - especially if you have more classes that shoule be checked. :-) Kind regards robert