From mboxrd@z Thu Jan 1 00:00:00 1970 From: D M German Subject: bug in expansion of variables in babel Perl Date: Sun, 24 Feb 2013 01:16:05 -0800 Message-ID: <87ppzq138q.fsf@mn.cs.uvic.ca> Reply-To: dmg@uvic.ca Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([208.118.235.92]:34399) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U9Xgu-0004Qy-Dl for emacs-orgmode@gnu.org; Sun, 24 Feb 2013 04:16:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U9Xgo-0003Ds-8s for emacs-orgmode@gnu.org; Sun, 24 Feb 2013 04:16:16 -0500 Received: from mail-pb0-f46.google.com ([209.85.160.46]:36451) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U9Xgn-0003DI-Uh for emacs-orgmode@gnu.org; Sun, 24 Feb 2013 04:16:10 -0500 Received: by mail-pb0-f46.google.com with SMTP id uo15so1159560pbc.5 for ; Sun, 24 Feb 2013 01:16:09 -0800 (PST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Hi Everybody, I found a bug in the Babel perl code. When a table is used as input, the values of the table are not escaped. In fact, they are surrounded by double quotes " instead of single ones '. This means that special characters are interpreted: $, and @ | jon #+name: output(data=patito) #+begin_src perl :results output print "Begin\n"; print $$data[0][0], "\n"; print "End\n"; #+end_src #+RESULTS: output : Begin : Jon : End ---------------------------------------------------------------------- I see two ways to solve this. The first is simply to replace the output format of the variable from "%S" to "'%s'" (use quotes '). The other one is to optionally escape the fields of the table (which is more complicated, and would require replacing each). The third one is a combination of both: replace them only if desired, via some header configuration variable. diff --git a/lisp/ob-perl.el b/lisp/ob-perl.el index ccd3826..2f795aa 100644 --- a/lisp/ob-perl.el +++ b/lisp/ob-perl.el @@ -75,7 +75,7 @@ The elisp value, VAR, is converted to a string of perl source code specifying a var of the same value." (if (listp var) (concat "[" (mapconcat #'org-babel-perl-var-to-perl var ", ") "]") - (format "%S" var))) + (format "'%s'" var))) Debugging perl is very cumbersome in org-mode. It would be nice to have a feature to export the source to a file. This is because the variable expansion needs to be done before the code can be used (hence simply cut and paste does not work, nor shell-command-on-region) I used the org-babel-perl-command variable to replace perl with a script that simply wrote to a file. It would be nice to be able to write the script created by org a file, so this can be debugged (it would have the variable definitions). Maybe this is already a feature and I don't know about it. As we are into it, I found this declaration to be very useful. ---------------------------------------------------------------------- (setq org-babel-perl-wrapper-method " use strict; sub org_columns { my ($table) = @_; my $y = $$table[0]; return scalar(@$y); } sub org_rows { my ($table) = @_; return scalar(@$table); } sub main { %s } my @r = main; open(o, \">%s\"); print o join(\"\\n\", @r), \"\\n\"") ---------------------------------------------------------------------- It does two things: it uses strict, so undeclared variables create errors, and it also creates two functions: org_columns and org_rows that, when used on the variable declared as input, return its number of columns and rows: my $rows = org_rows($data); my $columns = org_columns($data); the only problem with using strict is that variables would have to be defined with "my" too: so that would require this patch: diff --git a/lisp/ob-perl.el b/lisp/ob-perl.el index ccd3826..82f8086 100644 --- a/lisp/ob-perl.el +++ b/lisp/ob-perl.el @@ -62,7 +62,7 @@ This function is called by `org-babel-execute-src-block'." "Return list of perl statements assigning the block's variables." (mapcar (lambda (pair) - (format "$%s=%s;" + (format "my $%s=%s;" (car pair) (org-babel-perl-var-to-perl (cdr pair)))) (mapcar #'cdr (org-babel-get-header params :var)))) Finally, if interested, i can write a couple of examples for Perl that could help people who want to use it. thanks again, -- Daniel M. German "Great algorithms are Francis Sullivan -> the poetry of computation" http://turingmachine.org/ http://silvernegative.com/ dmg (at) uvic (dot) ca replace (at) with @ and (dot) with .