emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Multiple named code blocks


From: mooss
Subject: Multiple named code blocks
Date: Sat, 28 Nov 2020 22:35:05 +0000

Hi,

I have been using org-mode for almost three years and I loved it so much that I started working on a literate programming tool based on it.
One particular technique that I use is having multiple named code blocks, like so:

#+begin_src perl :noweb yes :results output
<<Before foo>>
sub foo {
    <<In foo>>
}
foo;
#+end_src

#+name: Before foo
#+begin_src perl
print "Before foo definition.\n";
#+end_src

#+name: Before foo
#+begin_src perl
my $value = 'Inside foo call';
#+end_src

#+name: In foo
#+begin_src perl
print $value . "\n";
#+end_src

This technique worked without issue until I recently updated Emacs and org-mode with it.
I do not know the version of org-mode I was using before, but this was with Emacs 26.3 and I upgraded to Emacs 27.1 with org-mode 9.4 according to the information at the top of elpa/org-plus-contrib-20201116/org.el.

Before the update, the code block after expansion (obtained with org-babel-expand-src-block via the C-c C-v C-v shortcut) looked like this:
#+begin_src perl
print "Before foo definition.\n";
my $value = 'Inside foo call';
sub foo {
    print $value . "\n";
}
foo;
#+end_src

Now the definition of $value is gone:
#+begin_src perl
print "Before foo definition.\n";
sub foo {
    print $value . "\n";
}
foo;
#+end_src

I have looked at the info manual so I realise that according to "15.2 Structure of Code Blocks": "For duplicate names, Org mode’s behavior is undefined" so it follows that:
- Up until now, I was incorrectly assuming that duplicated named code blocks were supposed to result in them being concatenated in the noweb expansion phase.
- This is not a bug report, org-mode is working as documented.

I find this technique pretty useful for two reasons:
1. Importing packages right when they are needed.
2. Declaring variables in a broader scope than the one where they are first used.
    Here is an short example of this kind of situation:

    #+begin_src perl :noweb no
    # Expansion of <<Variable declarations>>:
    my $even_counter = 0;
    my @array = (4, 8, 15, 16, 23, 42);
    # A
    # lot
    # of
    # other
    # code
    # [...]
    foreach my $n (@array) {
        # Expansion of <<Array processing>>:
        $even_counter++ if $n % 2 == 0;
    }
    print "$even_counter";
    #+end_src

    In this example, $even_counter could not have been declared on the spot.
    Of course, this example is too basic to really paint the usefulness of this technique but an actual example would be too long, the goal here is just to explain the general idea.

With all that being said I would suggest to define the behaviour for multiple named code blocks as resulting in a concatenation of the code blocks, in the order of their apparition.
If you agree about defining this behaviour but think adapting the implementation is of low priority, I could try to implement it myself though I have little experience in emacs-lisp development beyond basic configuration and no experience whatsoever in contributing to FOSS, but I'm willing to start in both domains.

Best regards,
Félix


reply via email to

[Prev in Thread] Current Thread [Next in Thread]