emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Multiple named code blocks
@ 2020-11-28 22:35 mooss
  2020-11-28 22:59 ` Tom Gillespie
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: mooss @ 2020-11-28 22:35 UTC (permalink / raw)
  To: emacs-orgmode@gnu.org

[-- Attachment #1: Type: text/plain, Size: 2967 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 4673 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-30 11:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-28 22:35 Multiple named code blocks mooss
2020-11-28 22:59 ` Tom Gillespie
2020-11-29  0:40   ` mooss
2020-11-29  3:24 ` Greg Minshall
2020-11-30 11:38   ` mooss
2020-11-29  8:28 ` Diego Zamboni
2020-11-30 11:39   ` mooss

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).