A dispute, and finally a ban on irc.freenode.net/#perl, led me to investigate the differences between CORE::open and IO::File. The claim: both return the same thing. I was arguing to never use CORE::open, per the docs, experience, and for added clarity. In my eyes IO::File is more easily extended, and transparent in its operations.
Here is some of the conversation, I got a kickban, so I lost chanlogs. Lets try to clear it up.
11:43 <mauke> CORE::open is an interface to IO::Handle
11:43 <mauke> also, IO::Handle is from 5.003; three-arg open is from 5
+.6
11:44 <mauke> clearly open is more modern
It certainly isn't an interface *to* IO::Handle, at best it has some similarities to the interface *of* IO::Handle. Here is what the docs say on this. Now, that I read them, I can see how it is confusing.
File handles are now stored internally as type IO::Handle. The FileHandle module is still supported for backwards compatibility, but it is now merely a front end to the IO::* modules -- specifically, IO::Handle, IO::Seekable, and IO::File. We suggest, but do not require, that you use the IO::* modules in new code.
IO::Handle also touches on the fundamental differences between CORE::open's hack and itself.
Due to backwards compatibility, all filehandles resemble objects of class IO::Handle, or actually classes derived from that class. They actually aren't. Which means you can't derive your own class from IO::Handle and inherit those methods.
So I wrote a test on the two. For these tests, oofh is the filehandle opened with IO::File, while fh is the CORE::open version. Lets get some data! Comments added later.
## Two different reference types
ok 2 - oofh is a reference ## though to an object.
ok 3 - fh is a reference ## base type glob
not ok 4 - they are the same reference
ok 5 - oofh can call new()
ok 6 - fh can call new()
ok 7 - oofh can call new()->new() ## joy continues
not ok 8 - fh can call new()->new() ## joy stops
## Both can do these, confusing isn't it...
ok 9 - oofh autoflushed
ok 10 - fh autoflushed
## But only one ->can('autoflush'), eh perl API I miss you.
ok 11 - oofh can autoflush
not ok 12 - fh can autoflush
## Only one is a true "object"
ok 13 - oofh is an object per S:U:blessed()
not ok 14 - fh is an object per S:U:blessed()
## But both are true filehandles
ok 15 - oofh is an filehandle per S:U:openhandle()
ok 16 - fh is an filehandle per S:U:openhandle()
## Revist test number #6 but with the byproduct of using IO::File to b
+egin with.
## This one is amusing.
not ok 17 - fh can call new wo/ IO::Handle loaded
I feel as strongly as ever, even though I didn't know fh's with CORE::open could $fh->autoflush, that all FH should utilize IO::File, and not CORE::open.
The cause of this dispute was wanting to revise docs for novices. I argue for ignoring CORE::open. People shouldn't learn it first, if ever, in my eyes. If you want to revise the learning curve of perl, it is better to leave it out. The syntax is also scary for a lot of people. Who passes in a reference to a localized variable in a function anyway? If I wrote something that permitted silent failures and had a subroutine definition of.
sub _give_me_a_variable_to_hack_by_reference( my $foo );
Most programmers, perl and otherwise, would rightfully wtf me to oblivion. Also, what gives with a method call to a non-blessed-object, is there anything else in perl that breaks the API in such an unintuitive way?
Oh you can find the test at
http://gist.github.com/110655