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?