4

How can I save the temporary file that is used to run the script in a babel code block? I need to debug why the perl mode is not able to read values as tables any more.

Example:

#+BEGIN_SRC perl 
print "hello world\n";
#+END_SRC

this outputs:

#+RESULTS:
#+begin_example
1
#+end_example

I would like to debug see what are the contents of the file sent to perl so I can debug its conversion to org.

Here is another example:

#+begin_src perl 
my @array;
foreach $a (1..10) {
   print "$a\n";
   push @array, $a;
}
(1,2,3);
#+end_src

#+begin_example
3
#+end_example
4
  • Are trying to see what the rendered src block looks like? Providing a simple hello world example would be very helpful. Also please provide your emacs version and org-mode version. Thanks!
    – Melioratus
    Commented Jun 23, 2018 at 4:59
  • Thank you for adding the examples! I can answer your question now.
    – Melioratus
    Commented Jun 23, 2018 at 20:12
  • Thank you. Support for perl used to be better, but a major rework on babel broke it, so I am trying to debug it and fix it.
    – dmg
    Commented Jun 23, 2018 at 22:09
  • What version of emacs, org-mode and perl are you using? I'm happy help troubleshoot in chat room on weekends if would like.
    – Melioratus
    Commented Jun 23, 2018 at 23:46

2 Answers 2

5

There are multiple issues going on, which I will do my best to address in a language agnostic manner.

Short Generic Answer

Use org-babel-expand-src-block1 to preview code that will be executed in the temporary file.

  1. Place cursor, i.e. the point, inside the code block on on the #+BEGIN_SRC line.
  2. Press C-c C-v v to open new Org-Babel Preview buffer.
  3. Debug code using one of the following methods:
    • Use the built-in debugger(s) configured in your init settings. The preview buffer should be using the language major and minor modes so any of the debugging tools which you have configured should be available.
    • If the debug tools are not enabled for the preview buffer, press C-x C-w to write the preview buffer to new file which can be loaded into an external debugger.

Other Issues - Generic Tips and Tricks Debugging Code Blocks in org-mode.

  • What caused this unexpected result?

    By default, src blocks display the value returned by last evaluated statement instead of the printed output of the block.

    Caveat: The default behavior depends on how the specific language was implemented in org-mode so you may need to check.

    • Example 1

      #+BEGIN_SRC perl
         print "hello world\n";
      #+END_SRC
      
      #+RESULTS:
      : 1
      

      The result is 1 because print statement returned 1.

    • Example 2

      #+begin_src perl 
         my @array;
         foreach $a (1..10) {
            print "$a\n";
            push @array, $a;
         }
         (1,2,3);
      #+end_src
      
      #+RESULTS:
      : 3
      

      The result is 3 because (1,2,3); list statement returned length 3.

    • Example 3 - No need to print literal strings.

      #+BEGIN_SRC perl
        "hello world";
      #+END_SRC
      
      #+RESULTS:
      : hello world
      

      The result is hello world because "hello world"; statement returned hello world.

    • Example 4 - If language supports arrays then use array syntax.

      #+begin_src perl
         [1,2,3];
      #+end_src
      
      #+RESULTS:
      | 1 |
      | 2 |
      | 3 |
      

      The result is table because the implementation converted [1,2,3]; into ((1) (2) (3)).

    • Example 5 - Some languages, e.g. perl, will need you add extra syntax to get the results you expected.

      #+begin_src perl 
        my @array;
        foreach $a (1..3) {
           print "$a\n";
           push @array, $a;
        }
        [@array]
      #+end_src
      
      #+RESULTS:
      | 1 |
      | 2 |
      | 3 |
      
  • Example 6 - Add output option to :results header if you really want the output printed to STDOUT.

    • Simple output

      #+begin_src perl  :results output    
        my @array;
        foreach $a (1..3) {
           print "Number $a\n";
           push @array, $a;
        }
        [@array]
      #+end_src
      
      #+RESULTS:
      : Number 1
      : Number 2
      : Number 3
      
    • Not so simple output

      #+begin_src perl :results code output    
        use Data::Dumper;
        my @array;
        foreach $a (1..3) {
           push @array, $a;
        }
        print qq(my ) . Data::Dumper->Dump([\@array], [qw(*array)]);
      #+end_src
      
      #+RESULTS:
      #+BEGIN_SRC perl
      my @array = (
             1,
             2,
             3
           );
      #+END_SRC
      

Thanks for asking a great question! Hope this helped!

This code was tested using:
emacs version: GNU Emacs 25.2.1 (x86_64-unknown-cygwin, GTK+ Version 3.22.10)
Org mode version: 9.1.2

2
  • Thank you. I appreciate your help. I realized now my mistake was confusing (1,2,3) with [1,2,3]. Also, I have submitted a patch to org-mode's documentation with a description of the perl babel support (which didn't exist). If you don't mind, would you be ok if I use some of this text? thank you again.
    – dmg
    Commented Jun 28, 2018 at 9:02
  • @dmg - I’ve made the list vs array mistake in org-mode for years and only learned the fix while researching the answer to your question. Please share text if you think it will help. Another language agnostic debugging trick is to pass the results into a very simple elisp block that displays results as elisp data structure code. I’ll update my answer with the trick. Thanks for asking a great question!
    – Melioratus
    Commented Jun 28, 2018 at 14:13
0

AFAIK, there is no "official" way to do this: you cannot set a variable, say, to preserve these things. What I do in such cases is either 1) run the evaluation in edebug, examining variables along the way to figure out what file contains the script and then go save it; or 2) comment out temporarily the code that deletes the temp files at the end of the evaluation. Both of these require some familiarity with elisp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.