From: Ilmari Heikkinen Date: 2004-12-12T06:23:06+09:00 Subject: Re: puts / print as method not keyword? la, 2004-12-11 kello 22:38, zuzu kirjoitti: > perhaps i don't just want the > default STDOUT but would like to specify tty3 versus tty9 or perhaps > window7 of some screen tty multiplexing session or how emacs manages > buffers, and so on... You would then replace STDOUT with e.g. STDERR, or even File.open("log","a"){|f| f.puts(string) } > oh, also, correct me if i'm wrong, but method/function argument > passing really should only be used for CONSTRAINTS _not_ DATA. > and so i also feel that > > string.puts(STDOUT) > > or i'm probably thinking more like > > string.puts {STDOUT} > > much more closely follows the so-called "Principle of Least Surprise". string.puts(STDOUT) creates a coupling, the string must call a method of the given object with itself as the argument. It must know that the object it's passed responds to #puts. Also, string.puts(STDOUT) modifies its argument (by printing a new line), which, to me at least, is a big no-no. STDOUT.puts(string) modifies only STDOUT. It doesn't (shouldn't) magically add an extra line to the string. And maybe it's better to have all objects respond to just #to_s instead of #puts, #print and #write. The postfix notation is tempting though, hmm.. If you look at unix pipes, they use a syntax like: method | method | method , last method taking care of doing things The difference to Ruby's method.method.method is that the shell pipes aren't namespaced to the preceding object. Ie. With shell pipes it'd be quite doable to except the following to work in every situation: gets | reverse | puts , because they are in the global namespace. What you pass through the pipe doesn't change the available methods. In ruby gets.reverse.puts creates a dependency chain. gets must return something that responds to reverse, and reverse must return something that responds to puts. Which is bad. So maybe we should emulate shell pipes in some other way? def in; yield self; end string.in{|s| STDOUT.puts(s)} Works in dataflow-style, too: string.in{|s| puts s; s}.reverse.in{|s| puts s} Keeps concerns to the objects whom they may concern (String doesn't have to know about what methods IO has, etc.), and doesn't do black-box modifications to its arguments. Comments?