Hi, Currently, defining classes or other constants inside a Ruby source code block like this fails with an "unexpected class definition in method body" error:
#+begin_src ruby class Three def number = 3 end Three.new.number #+end_src This happens because ob-ruby wraps the code in a method before evaling it, and classes can not be defined inside methods. Wrapping it inside a Ruby lambda instead makes this work. The two other options I could think of, `instance_exec` or simply a `begin ... end` block would both break the behaviour of toplevel `return` statements in the evaled code, which some people might rely on. The added tests ensure that `return` still works as before. cheers, Til
From 56ec93825f91c272159672ef00b4c1cd027aa6af Mon Sep 17 00:00:00 2001 From: Tilmann Singer <[email protected]> Date: Thu, 1 Jan 2026 23:32:35 +0100 Subject: [PATCH] ob-ruby: Wrap evaled code in lambda instead of method * lisp/ob-ruby.el (org-babel-ruby-wrapper-method, org-babel-ruby-pp-wrapper-method): wrap evaled Ruby code inside a lambda instead of a method. This way, defining constants such as classes becomes possible. * testing/lisp/test-ob-ruby.el: add tests for the result methods value and pp --- lisp/ob-ruby.el | 10 +++--- testing/lisp/test-ob-ruby.el | 60 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/lisp/ob-ruby.el b/lisp/ob-ruby.el index e7e470dc8..003fc809e 100644 --- a/lisp/ob-ruby.el +++ b/lisp/ob-ruby.el @@ -213,20 +213,18 @@ Session settings (`:ruby' header arg value) are taken from PARAMS." (defvar org-babel-ruby-wrapper-method " -def main() +results = (lambda do %s -end -results = main() +end).call File.open('%s', 'w'){ |f| f.write((results.class == String) ? results : results.inspect) } ") (defvar org-babel-ruby-pp-wrapper-method " require 'pp' -def main() +results = (lambda do %s -end -results = main() +end).call File.open('%s', 'w') do |f| $stdout = f pp results diff --git a/testing/lisp/test-ob-ruby.el b/testing/lisp/test-ob-ruby.el index 27f96f6da..c4d75a80f 100644 --- a/testing/lisp/test-ob-ruby.el +++ b/testing/lisp/test-ob-ruby.el @@ -78,6 +78,66 @@ s = \"6\" : 5 "))) +(ert-deftest test-ob-ruby/value () + (should + (equal 3 + (org-test-with-temp-text "#+begin_src ruby :results value +1 + 2 +#+end_src" + (org-babel-execute-src-block))))) + +(ert-deftest test-ob-ruby/value-with-class-definition () + (should + (equal 3 + (org-test-with-temp-text "#+begin_src ruby :results value +class Three + def result + 1 + 2 + end +end +Three.new.result +#+end_src" + (org-babel-execute-src-block))))) + +(ert-deftest test-ob-ruby/value-with-return () + (should + (equal 3 + (org-test-with-temp-text "#+begin_src ruby :results value +return 3 +2 +#+end_src" + (org-babel-execute-src-block))))) + +(ert-deftest test-ob-ruby/pp () + (should + (equal "3\n" + (org-test-with-temp-text "#+begin_src ruby :results pp +1 + 2 +#+end_src" + (org-babel-execute-src-block))))) + +(ert-deftest test-ob-ruby/pp-with-class-definition () + (should + (equal "3\n" + (org-test-with-temp-text "#+begin_src ruby :results pp +class Three + def result + 1 + 2 + end +end +Three.new.result +#+end_src" + (org-babel-execute-src-block))))) + +(ert-deftest test-ob-ruby/pp-with-return () + (should + (equal "3\n" + (org-test-with-temp-text "#+begin_src ruby :results pp +return 3 +2 +#+end_src" + (org-babel-execute-src-block))))) + (provide 'test-ob-ruby) ;;; test-ob-ruby.el ends here -- 2.52.0
signature.asc
Description: PGP signature
