On Thu, 2005-05-05 at 15:15, Aaron Sherman wrote: > Dash this all on the rocks if you want, but understand that this is not > an off-the-cuff reply, but something that I've spent a lot of time > mulling over [...] > First off, IMHO, open should be an alias for a closure-wrapped > constructor, like so: > > sub open := IO.new;
Some reading later, I see mixed references to &, but I thought & had been re-glommed for other purposes.... yep, pugs confirms & works. > This makes "open" the maximally > dwimish operator. You can always introduce a "sysopen" and "stdiopen" > and "sockopen", etc. if you want domain-specific behavior exclusively > (e.g. treat everything as a filename only, or as a host:port only, etc). This deserves a bit more detail than I gave it before (pardon, I'm typing as I debug work code). "open" as a verb is extremely ambiguous. In dictionary searches I see as many as 19 definitions just for the verb form. "open" as a POSIX function is not ambiguous at all. But will the POSIX model be the model on which P6 is based (as P5 was), or will the POSIX model simply be one of many models supported by open and other built-ins? I think that it's fair to say that Perl has grown beyond POSIX. If it also presents the URI model, that's not all bad, is it? Same goes for the Unix command-line conventions (e.g. cat's "-" special filename). I should be able to request a "pure POSIX" open, but I'm not sure it should be the default for one of English's most powerfully flexible verbs. > and perhaps even > > File::Copy::copy("-","-"); This brings up something interesting. If we have: sub File::Copy::copy(IO $file1, IO $file2) {...} the above doesn't work. I think I want: sub File::Copy::copy(IO $file1 :r, IO $file2 :w) {...} But does that work the way I think it does? Does that end up calling: IO.new("-", :r); and IO.new("-", :w); ? If not, how do I ensure that this works correctly? > Sure enough, there's an easy way: > > class IO is ParrotIO does RegisteredStringConstructor {...} > role RegisteredStringConstructor { > has %:registry; > sub register(Any $pattern, Type $type) { > %:registry{$pattern} = $type; > } > multi method new(Str $string,*%rest) { > for %:registry.keys -> $pat { > if $string ~~ $pat { > return > %:registry{$pat}.bless(:string($string),*%rest); > } > } I would need some error handling here, and possibly would need to defer to a parent as a fallback. That brings up the idea of delegation... should this be handled by delegation instead of the way I've done it? Not sure. I'm still trying to figure out how to make this scope correctly so that: use IO; { use IO::URI :open; open("http://www.perl.org/",:r); } open("http://www.perl.org",:r); opens two very different things: a socket to a host and port as directed by a URI vs a file named "www.perl.org" in a directory called "http:". > Optional export features of IO::* could allow: > > * pipeline command execution > * thread and/or process coupling > * handle duping > * much more > > Thus, you would control these features like so: > > use IO; > use IO::Funky :register_string_open_funkiness; > open("funk",:w); Which is probably just the tip of the iceberg. You might, for example, want to lay out a user-defined filesystem, or open database tables as files, etc. Of course, you can do all of this explicitly through OO syntax, but it would be nice to uniformly export locator semantics as strings so that command-line and other string-based user interaction could be made more powerful with a single "use". -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback