treat an obj with print method as a file in -eos logic
authorSteve Hancock <perltidy@users.sourceforge.net>
Sat, 19 Mar 2022 19:20:47 +0000 (12:20 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Sat, 19 Mar 2022 19:20:47 +0000 (12:20 -0700)
docs/eos_flag.md
lib/Perl/Tidy.pm

index d32396acb0c50d88ed7742a340e85d68817525fa..2e38e0af706327a7dc35ec5022450d6c437d2fca 100644 (file)
@@ -140,10 +140,13 @@ it is processed by perltidy at three well-defined points:
     - at the intermediate stage as it is processed
     - when it is leaves to its destination
 
-Since 'C' mode only has meaning within Perl scripts, a rule is that
-outside of the realm of Perl the text must exist in 'B' mode.  So the source
-can only be in 'C' mode if it arrives by a call from another Perl program, and
-the destination can only be in 'C' mode if the destination is a Perl program.
+Since 'C' mode only has meaning within Perl scripts, a rule is that outside of
+the realm of Perl the text must exist in 'B' mode.  So the source can only be
+in 'C' mode if it arrives by a call from another Perl program, and the
+destination can only be in 'C' mode if the destination is a Perl program. If
+the destination is a file, or object with a print method, then it will be
+assumed to be ending its existance as a Perl string and will be placed in an
+end state which is 'B' mode.
 
 Let us make a list of all possible sets of modes to be sure that all cases are
 covered.  If each of the three states could be in 'B' or 'C' mode then we
@@ -181,5 +184,3 @@ Referring back to the full table, note that case 7, the C->C->B route, is an
 unusual but possible situation involving a source string being sent directly
 to a file.  It is the only situation in which perltidy does an encoding
 without having done a corresponding previous decoding.
-
-
index 8eb5d0743b7de48d23e7463a404220dba02b31d9..01edc7467b319cf05d314ed06f6c42259280ccbe 100644 (file)
@@ -196,7 +196,7 @@ sub streamhandle {
                     $New = sub { undef };
                     confess <<EOM;
 ------------------------------------------------------------------------
-No 'getline' method is defined for object of class $ref
+No 'getline' method is defined for object of class '$ref'
 Please check your call to Perl::Tidy::perltidy.  Trace follows.
 ------------------------------------------------------------------------
 EOM
@@ -216,7 +216,7 @@ EOM
                     $New = sub { undef };
                     confess <<EOM;
 ------------------------------------------------------------------------
-No 'print' method is defined for object of class $ref
+No 'print' method is defined for object of class '$ref'
 Please check your call to Perl::Tidy::perltidy. Trace follows.
 ------------------------------------------------------------------------
 EOM
@@ -1400,14 +1400,32 @@ EOM
         # possible encoding at the end of processing.
         my $destination_buffer;
         my $use_destination_buffer;
-        if (
-            ref($destination_stream)
-            && (   ref($destination_stream) eq 'SCALAR'
-                || ref($destination_stream) eq 'ARRAY' )
-          )
-        {
+        my $encode_destination_buffer;
+        my $ref_destination_stream = ref($destination_stream);
+        if ($ref_destination_stream) {
             $use_destination_buffer = 1;
             $output_file            = \$destination_buffer;
+
+            # Strings and arrays use special encoding rules
+            if (   $ref_destination_stream eq 'SCALAR'
+                || $ref_destination_stream eq 'ARRAY' )
+            {
+                $encode_destination_buffer =
+                  $rOpts->{'encode-output-strings'} && $decoded_input_as;
+            }
+
+            # An object with a print method will use file encoding rules
+            elsif ( $ref_destination_stream->can('print') ) {
+                $encode_destination_buffer = $is_encoded_data;
+            }
+            else {
+                confess <<EOM;
+------------------------------------------------------------------------
+No 'print' method is defined for object of class '$ref_destination_stream'
+Please check your call to Perl::Tidy::perltidy. Trace follows.
+------------------------------------------------------------------------
+EOM
+            }
         }
 
         $sink_object = Perl::Tidy::LineSink->new(
@@ -1796,7 +1814,7 @@ EOM
             # source, it encodes before returning.
             $rstatus->{'output_encoded_as'} = '';
 
-            if ( $rOpts->{'encode-output-strings'} && $decoded_input_as ) {
+            if ($encode_destination_buffer) {
                 my $encoded_buffer;
                 eval {
                     $encoded_buffer =
@@ -1815,13 +1833,25 @@ EOM
                 }
             }
 
-            # Final string storage
+            # Send data for SCALAR, ARRAY & OBJ refs to its final destination
             if ( ref($destination_stream) eq 'SCALAR' ) {
                 ${$destination_stream} = $destination_buffer;
             }
             else {
                 my @lines = split /^/, $destination_buffer;
-                @{$destination_stream} = @lines;
+                if ( ref($destination_stream) eq 'ARRAY' ) {
+                    @{$destination_stream} = @lines;
+                }
+
+                # destination is object with print method
+                else {
+                    foreach (@lines) {
+                        $destination_stream->print($_);
+                    }
+                    if ( $ref_destination_stream->can('close') ) {
+                        $destination_stream->close();
+                    }
+                }
             }
         }
         else {