Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^3: Split tab-separated file into separate files, based on column name (open on demand)

by Eily (Monsignor)
on Aug 26, 2020 at 15:26 UTC ( [id://11121105]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Split tab-separated file into separate files, based on column name (open on demand)
in thread Split tab-separated file into separate files, based on column name

This might be considered dirty in a real Perl script but should be acceptable in a one-liner.
100% agree with that sentence (which says a lot, since the sentence is "this might be").

You could use operator overloading to replicate that feature. "Value" > file("path"); or "Value" >> file("path") where file returns an object that overloads > and >>

Or you could do something closer to C++:

fstream("path") << 120 << " in hexadecimal is " << ctrl::hex << 120; fstream("logs", "a") << ctrl::autoline << "I'm adding this line to the + logs" << "and also this line";

  • Comment on Re^3: Split tab-separated file into separate files, based on column name (open on demand)
  • Select or Download Code

Replies are listed 'Best First'.
Re^4: Split tab-separated file into separate files, based on column name (open on demand)
by tobyink (Canon) on Aug 27, 2020 at 16:40 UTC

      Great module! So with IO::All this could yield:

      $ perl -MIO::All -F'/\t/' -lnae '@files = @F, next if 1 .. 1; @f = @fi +les; $_ >> io(shift @f) for @F' <<EOF id name position 1 Nick boss 2 George CEO 3 Christina CTO EOF $ paste id name position 1 Nick boss 2 George CEO 3 Christina CTO

      EDIT Removed do statement.

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
Re^4: Split tab-separated file into separate files, based on column name (open on demand)
by LanX (Saint) on Aug 26, 2020 at 15:38 UTC
    > You could use operator overloading

    I don't think it's a good idea to overload two very different operators like > "greater-than" and >> "shift".

    That's begging for inconsistency problems. (like syntax, precedence, name it ...)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re^4: Split tab-separated file into separate files, based on column name (tangent = open on demand => stream-like)
by pryrt (Abbot) on Aug 26, 2020 at 17:32 UTC
    So it got me curious, and I did a quick-and-dirty test implementation of scalar > file() and fstream() << scalar. But I get the "useless use of ... in void context" warnings.

    So my tangential question: Is there a way to "export" the no warnings 'void' from inside the streaming package, rather than requiring it in ::main? It would be best if it could just turn off the warnings for the streaming objects, but leave the warnings on for non-overloaded uses of comparison and bitshift. I tried putting the no-warnings inside the overloaded functions, to try to keep the scope limited, but that's not the right place to prevent the warning. (Yes, I understand this isn't necessarily good practice, or "nice" to the external user. This is just for my own curiosity, and not something I'd put in practical code.)

    #!/usr/bin/perl -l use warnings; use strict; # [id://11121105] # as suggested, have file() return an object which overloads > and >>, + so you can overwrite and append # "value" > file('to_overwrite'); "value" >> file('to_append'); # or have fstream() return an object which overloads just <<, for a ve +ry c+_+-eseque # fstream("path") << 120 << " in hexadecimal is " << ctrl::hex << 12 +0; END { print "="x10 }; { package fout; use autodie; use overload '>' => \&overwrite, '""' => sub { \${$_[0]} }, ; sub file($) { print __PACKAGE__, "::file($_[0])"; return bless \$_[0], __PACKAGE__; } sub overwrite { # 'value' > file($f) ==> overwrite(\$f, 'value', 1) my ($self, $value, $swap) = @_; if($swap) { open my $fh, '>', $$self; print {$fh} $value; } else { warn "not sure how to clobber scalar: `file($$self) > $val +ue`"; } return $self; } } *file = \&fout::file; #no warnings 'void'; #file('zzz') > "value"; #fout::overwrite(file('xxx'), 'manual', 1); # this wrote the file corr +ectly #'blah > file(yyy)' > file('yyy'); # will this? #print __PACKAGE__, "::"; { package fstream; use autodie; use overload '<<' => \&append, ; sub fstream($) { print __PACKAGE__, "::fstream($_[0])"; return bless \$_[0], __PACKAGE__; } sub fclobber($) { print __PACKAGE__, "::clobber($_[0])"; open my $fh, '>', $_[0]; return bless \$_[0], __PACKAGE__; } sub append { my ($self, $value, $swap) = @_; if(!$swap) { open my $fh, '>>', $$self; print {$fh} $value; } else { warn "not sure how to clobber scalar: `$value << file($$se +lf)`"; } return $self; } } *fstream = \&fstream::fstream; *fclobber = \&fstream::fclobber; 'value' << fstream('szsz'); fstream('sss') << "first"; fstream('sss') << "second" << "third"; fclobber('clb') << 'one' << 'and another';
      That's another good example why overloading is doomed to fail if the operator isn't semantically compatible.

      Regarding your question:

      Either you can try to manipulate the __WARN__ handler in %SIG

      Or you can try exporting warnings inside import() like demonstrated in Modern::Perl

      (And I agree about the productive code part. ;)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      Updates

      Rephrased and linked

        I'm not much of a fan of operator overloading anyway. But I thought it was a nice thought experiment, and again, maybe acceptable for oneliners.

        I still tried to cheat the system and go around the "useless use [...] in voix context" by using <<= instead of << because $magic << "Value"; returns $magic itself so $magic <<= "Value"; works fine.
        Except it failed when trying to turn this: $magic << "Value" << "Other value"; into $magic <<= "Value" <<= "Other value";, because << is a left associative operator and <<= is a right associative one. Meanig you've just turned ($magic << "Value") << "Other"; into $magic <<= ("Value" <<= "Other");. Whoops.

        So yes, the lesson is don't add new semantic to operators kid (yup, I'm looking at you C++).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11121105]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-24 19:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found