On Sun, 16 Aug 2009, David Green wrote:
On 2009-Aug-15, at 9:22 am, Jon Lang wrote:
IOW, your "outside the file" stuff is whatever can be done without
having to open the file, and your "inside the file" is whatever only
makes sense once the file has been opened. Correct?
Pretty much, yes.
If so, could you give some examples of how such a distinction could be
beneficial, or of how the lack of such a distinction is problematic?
Well, my main thought in this context is that the stuff that can be
done to the inside of a file can also be done to other streams -- TCP sockets
for example (I know, there are differences, but the two are a lot the same),
whereas metadata makes less sense in the context of TCP sockets; I guess this
was one of the thoughts that led me to want separate things here.
Well, I definitely think there needs to be a class that combines the inside
and the outside, or the data and the metadata. Certainly the separate parts
will exist separately for purposes of implementation, but there needs to be a
user-friendlier view wrapped around that. Or maybe there are (sort of) three
levels, low, medium, and high; that is, the basic implementation level (=P6
direct access to OS- and FS- system calls); the combined level, where an IO
or "File" object encompasses IO::FSnode and IO::FSdata, etc.; and a
gloss-over-the-details level with lots of sugar on top (at the expense of
losing control over some details).
Hmm. With the quoting idea, I don't see the need for a "both" type of
object. I mean, I'd see the code happening something like this:
if (path{/path/to/file}.e) {
@lines = slurp(path{/path/to/file});
}
Or...
if (path{/path/to/file}.e) {
$handle = open(path{/path/to/file});
}
(I'm using one of David's suggested syntaxes above, but I'm not
closely attached to it).
I guess what I'm saying here is that I think we can do the things
without people having to worry about the objects being separate unless they
care. So, separate objects, but hide it as much as possible. Is that
something you're fine with?
In fact, having q, Q, or qq involved at all strikes me as wrong,
since those three are specifically for generating strings.
Pathnames still are strings, so that's fine. In fact, there are different
Hmm. I'm not so sure; maybe I'm just being picky, but I want to
clarify things in case it's important (in other words, I'm thinking out loud
here to see if it helps).
First, Q and friends don't generate strings, they generate string-like
objects, which could be Str, or Match, or whatever. Think of quoting
constructs as a way of temporarily switching to a different sublanguage (cf.
regex), and you'll have the idea that I have in mind.
As for pathnames being strings, you may be right FSVO string. But I'd
say that, while they may be strings, they're not Str, but they do Str, as in
role IO::FSNode does Str {...}
(FSNode may not be the right name here, but is used for illustrative
purposes).
things going on here; one is to have a way of conveniently quoting strings
that contain a lot of backslashes. Just as Perl lets you pick different
quotation marks, to make it easier to quote strings that have a lot of " or '
characters, so it should have a way to make it easy to quote strings with a
lot of backslashes. (The most obvious example being Windows paths; but there
are other possibilities, such as needing to eval some code that already has a
lot of backslashes in it.)
Now, you can already turn backwhacking on or off via Q's :backslash adverb;
Q:qq includes :b (and Q:q recognises a few limited escape sequences like \\).
So you could say Q[C:\some\path], and you could add scalar interpolation to
say Q:s[C:\some\path\$filename]. But there's no way to have all of: literal
backslashes + interpolation + escaped sigils.
Perhaps instead of a simple :b toggle, we could have an :escape<Str> adverb
that defaults to :escape<\>? Then you could have
Q:scalar:escape("^")[C:\path\with\literal^$\$filename].
Maybe a global variable? It's an interesting idea, and I'll see how
others feel :).
The ultimate in "path literals" would be to establish a similar
"default delimiter". [...]
`path`.size # how big is the file? Returns number.
There's something that slightly jars me here... I don't like the quotation
returning an IO object. (I like the conciseness, but there's something a bit
off conceptually.)
Hmm. But doesn't normal quoting return a Str object? And regex
quoting return an object (Regex? Match? Something, anyway).
Now, isn't Q:path[/some/file] just creating an IO object? Unlike /foo/,
where "foo" just IS the pattern, "/some/file" is *not* an IO object, it's
just a filename. So if the special path-quoting returned an IO::File::Name
object, I would be perfectly happy. But you can't have $filename.size -- a
fileNAME doesn't have a size, the file itself does. To get from the filename
to the file, you need another step, and it's that extra step I don't like
We seem to agree that we're talking about at least three things here
(however much some of them are disguised).
- Paths (ie. file names, URLs, whatever)
- File metadata (IO::FSNode, etc)
- File data (what S32/IO calls IO::File -- the stuff inside the file)
The difference in our approaches is that you seem keen to integrate
closely the data and the metadata, whereas I'm trying to integrate the paths
and the metadata.
[Btw, I've snipped some stuff here that I disagree with, but have
already stated my case above, I think].
IO objects always to parse a literal string the right way. (I.e. "/" is made
to represent the official cross-platform path separator. Unless you parse
some literal text with Q:ntfs, which parses a literal "\" as "/"?? Or say
"use path-separator '\';" or something!)
Another problem, just to make things exciting:
$ echo $PATH
/home/wayland/local/bin:/usr/global/bin:/usr/local/bin:/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/sbin
Now, which of these is the path? The whole thing, or the individual
directory paths? And what's the path separator? Slash (/) or colon (:)? So
I think we need to distinguish between a search path, and a file/directory
path. So we'd be doing "use fs-path-separator Q '\';" (note the Q -- your
example would, I think, have needed a \\ in it).
Having said that, though, I like some of the ideas in the section
above.
In fact, path literals may be more pattern-like than string-like, when
and if you start taking wildcard characters into account:
if $file ~~ path[./*.txt] {
say "$file is a text file in the current working directory."
}
Is that just a regex, in fact?
No, we're talking about a globbing sublanguage (see the glob()
function). In p5, this could be done with the <> quotes, but S02 says that in
P6, that you need to use the "glob" function if you want this kind of
functionality. The "glob" language is different than regex. I was wanting to
replace the "glob" language with something more like XPath, but that idea was
vetoed by people who didn't want Tree-related objects to be part of the core,
so I'm doing that as a library.
Though, to speak of file-types, this particular example would I think better
be handled by:
if $file.type ~~ MIME("text/plain") {...}
Cool idea. How would the type be determined? Are you thinking of the
algorithms in the unix "file" utility? Please tell me you're not planning to
use filename extentions -- that's bad :).
:)
---------------------------------------------------------------------
| Name: Tim Nelson | Because the Creator is, |
| E-mail: wayl...@wayland.id.au | I am |
---------------------------------------------------------------------
----BEGIN GEEK CODE BLOCK----
Version 3.12
GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V-
PE(+) Y+>++ PGP->+++ R(+) !tv b++ DI++++ D G+ e++>++++ h! y-
-----END GEEK CODE BLOCK-----