From: Alexandru Popescu Date: 2006-01-20T17:52:22+09:00 Subject: Re: My Thought on the "Pickaxe book" (from a Ruby novice) #: ara.t.howard@noaa.gov changed the world a bit at a time by saying (astral date: 1/19/2006 9:10 PM) :# > On Fri, 20 Jan 2006, Mark Volkmann wrote: > >> I guess that's the part I don't get. In the majority the cases, I don't see >> how choosing a particular synonym better expresses the intention. >> >> For example, in the Hash class, has_key? = include? = key? = member? When I >> see include? and member? it's not immediately obvious to me whether they >> test whether a given object is present as a key or a value. has_key? and >> key? are more clear and I don't see a benefit to having both of them. > > i couldn't disagree more. names, for variables or methods, are of utmost > importance to better expresses intention: > > puts 'this makes sense even without knowing what set is!' if set.member? 42 > > > puts 'this is requires a comment' if s.has_key? 42 > With all due respect, I would say these tricks are used _after_ you master the API. The discussion (as far as i got it) was about leaning it (so _before_ mastering the API). And having 6 methods with different names is kind of confusing while learning. You are loosing a lot of time trying to identify if there are any differences between them. I agree with you that after mastering the API these may become handy. cheers, ./alex -- .w( the_mindstorm )p. ps: I guess this is pretty much in the idea of a series of blog posts that happen lately about human interfaces vs good APIs vs ... (iirc the start was somewhere on Martin Fowler's blog) >> That may be the best example. Here are some others. >> >> Enumerable: >> collect = map >> entries = to_a >> detect = find >> member? = include? >> find_all = select > > > p signals.detect{|sig| sig.freq > 42} > > p list.find{|x| x.freq > 42} > >> Hash: >> store = []= >> merge! = update >> has_value? = value? >> >> Integer: >> next = succ >> >> IO: >> pos = tell >> >> Kernel: >> fail = raise >> format = sprintf >> >> String >> next = succ >> next! = succ! >> >> Thread >> fork = start >> exit = kill = terminate > > for many synonyms consider duck typing usage as well - it's not only about > making sense when reading: > > if i have a lib that does this > > exit if bug > > then i can use it like this > > require 'lib' > > or like this > > successfully_loaded = Thread::new { > begin > require 'lib' > true > rescue SystemExit > nil > end > }.value > > puts "Thread#exit called in lieu of Kernel#exit - whew" unless successfully_loaded > > > the interface polymorism gained by synonyms is often handy. > > if i design a table class an initially design it around a hash and use > > table.store key, value > > in my code, but later decide i need to store multiple values under one key and > switch to a database backend i can simply have a store method that looks like > > def store key, *values > ... > end > > and then start using > > table.store key, v0, v1, v2 > > without changing the other code. if i'd used > > table[key] = value > > all over the plase initially i'd have a strange mixture of methods and would > require a special [] method for storing one value, which would quickly become > code smell. in this case the abstract idea of 'storing' something under a key > was more appropriate to my design in the first place so using this interface > saved me grief later. > > synonyms exist elsewhere for clarity in ruby too > > unless == if not > > thankfully. > > regards. > > -a