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


Reply via email to