scriptorium 0.6.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. checksums.yaml +4 -4
  2. data/assets/icons/social/reddit.png +0 -0
  3. data/assets/icons/social/x-logo.png +0 -0
  4. data/assets/imagenotfound.jpg +0 -0
  5. data/bin/sblog +84 -5
  6. data/bin/scriptorium +1 -0
  7. data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +0 -1
  8. data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +0 -29
  9. data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +0 -19
  10. data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +1 -1
  11. data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +1 -1
  12. data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +1 -1
  13. data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +0 -10
  14. data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +1 -4
  15. data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
  16. data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
  17. data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
  18. data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
  19. data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
  20. data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
  21. data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
  22. data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
  23. data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
  24. data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
  25. data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
  26. data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
  27. data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
  28. data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
  29. data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
  30. data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
  31. data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
  32. data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
  33. data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
  34. data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
  35. data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
  36. data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
  37. data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
  38. data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
  39. data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
  40. data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
  41. data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
  42. data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
  43. data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
  44. data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
  45. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
  46. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
  47. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
  48. data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
  49. data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
  50. data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
  51. data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
  52. data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
  53. data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
  54. data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
  55. data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
  56. data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
  57. data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
  58. data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
  59. data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
  60. data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
  61. data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
  62. data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
  63. data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
  64. data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
  65. data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
  66. data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
  67. data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
  68. data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
  69. data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
  70. data/doc/imported/0018-ruby-puns/post.html +46 -0
  71. data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
  72. data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
  73. data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
  74. data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
  75. data/doc/imported/0020-fffff/metadata.txt +7 -0
  76. data/doc/imported/0020-fffff/post.html +24 -0
  77. data/doc/imported/0020-fffff/source.lt3 +12 -0
  78. data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
  79. data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
  80. data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
  81. data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
  82. data/doc/imported/0023-doctor-sleep/post.html +63 -0
  83. data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
  84. data/doc/imported/0024-just-a-test/metadata.txt +7 -0
  85. data/doc/imported/0024-just-a-test/post.html +24 -0
  86. data/doc/imported/0024-just-a-test/source.lt3 +12 -0
  87. data/doc/imported/import_summary.txt +98 -0
  88. data/doc/livetext-informal-spec.txt +65 -0
  89. data/doc/myuserdoc/ch-0.lt3 +31 -0
  90. data/doc/myuserdoc/ch-1.lt3 +37 -0
  91. data/doc/myuserdoc/ch-10.lt3 +22 -0
  92. data/doc/myuserdoc/ch-2.lt3 +37 -0
  93. data/doc/myuserdoc/ch-3.lt3 +19 -0
  94. data/doc/myuserdoc/ch-4.lt3 +43 -0
  95. data/doc/myuserdoc/ch-5.lt3 +22 -0
  96. data/doc/myuserdoc/ch-6.lt3 +19 -0
  97. data/doc/myuserdoc/ch-7.lt3 +16 -0
  98. data/doc/myuserdoc/ch-8.lt3 +13 -0
  99. data/doc/myuserdoc/ch-9.lt3 +19 -0
  100. data/doc/myuserdoc/tweak.rb +18 -0
  101. data/doc/{userdoc-toc.txt → myuserdoc/userdoc-toc.txt} +27 -27
  102. data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
  103. data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
  104. data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
  105. data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
  106. data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
  107. data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
  108. data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
  109. data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
  110. data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
  111. data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
  112. data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
  113. data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
  114. data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
  115. data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
  116. data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
  117. data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
  118. data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
  119. data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
  120. data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
  121. data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
  122. data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
  123. data/doc/old-posts/0024-just-a-test.lt3 +12 -0
  124. data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
  125. data/doc/old-repo +1 -0
  126. data/doc/reddit_integration.md +2 -2
  127. data/doc/user.lt3 +0 -3
  128. data/lib/scriptorium/api.rb +1811 -78
  129. data/lib/scriptorium/banner_svg.rb +55 -68
  130. data/lib/scriptorium/contract.rb +3 -2
  131. data/lib/scriptorium/exceptions.rb +133 -102
  132. data/lib/scriptorium/helpers.rb +282 -82
  133. data/lib/scriptorium/post.rb +81 -17
  134. data/lib/scriptorium/reddit.rb +1 -1
  135. data/lib/scriptorium/repo.rb +478 -164
  136. data/lib/scriptorium/standard_files.rb +30 -396
  137. data/lib/scriptorium/support/common_js/clipboard.js +35 -0
  138. data/lib/scriptorium/support/common_js/content-loader.js +187 -0
  139. data/lib/scriptorium/support/common_js/navigation.js +52 -0
  140. data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
  141. data/lib/scriptorium/support/config/reddit_template.txt +17 -0
  142. data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/social.txt +1 -0
  143. data/lib/scriptorium/support/highlight/css.txt +2 -0
  144. data/lib/scriptorium/support/highlight/custom.css +119 -0
  145. data/lib/scriptorium/support/highlight/js.txt +1 -0
  146. data/lib/scriptorium/support/post_index/config.txt +15 -0
  147. data/lib/scriptorium/support/post_index/style.css +55 -0
  148. data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
  149. data/{test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 → lib/scriptorium/support/templates/initial_post.lt3} +5 -5
  150. data/lib/scriptorium/support/templates/post.lt3 +104 -0
  151. data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt → lib/scriptorium/support/theme/header.lt3} +1 -1
  152. data/lib/scriptorium/theme.rb +83 -70
  153. data/lib/scriptorium/version.rb +2 -2
  154. data/lib/scriptorium/view.rb +194 -149
  155. data/lib/scriptorium.rb +24 -1
  156. data/lib/skeleton.rb +4 -1
  157. data/scriptorium.gemspec +2 -1
  158. data/test/WEB_INTEGRATION_README.md +196 -0
  159. data/test/all +40 -0
  160. data/test/banner_svg/unit.rb +267 -35
  161. data/test/config/deployment.txt +5 -0
  162. data/test/integration/integration_test.rb +7 -7
  163. data/test/integration/preview_flow_test.rb +94 -0
  164. data/test/livetext_plugin_test.rb +453 -182
  165. data/test/manual/banner-tests/test01.html +82 -18
  166. data/test/manual/banner-tests/test02.html +82 -18
  167. data/test/manual/banner-tests/test03.html +82 -18
  168. data/test/manual/banner-tests/test04.html +89 -25
  169. data/test/manual/banner-tests/test05.html +89 -25
  170. data/test/manual/banner-tests/test06.html +89 -25
  171. data/test/manual/banner-tests/test07.html +89 -25
  172. data/test/manual/banner-tests/test08.html +82 -18
  173. data/test/manual/banner-tests/test09.html +82 -18
  174. data/test/manual/banner-tests/test10.html +82 -18
  175. data/test/manual/banner-tests/test11.html +82 -18
  176. data/test/manual/banner-tests/test12.html +82 -18
  177. data/test/manual/banner-tests/test13.html +82 -18
  178. data/test/manual/banner-tests/test14.html +82 -18
  179. data/test/manual/banner-tests/test15.html +82 -18
  180. data/test/manual/banner-tests/test16.html +82 -18
  181. data/test/manual/banner-tests/test17.html +82 -18
  182. data/test/manual/banner-tests/test18.html +90 -26
  183. data/test/manual/banner-tests/test19.html +90 -26
  184. data/test/manual/banner-tests/test20.html +90 -26
  185. data/test/manual/banner-tests/test21.html +90 -26
  186. data/test/manual/banner-tests/test22.html +90 -26
  187. data/test/manual/banner-tests/test23.html +90 -26
  188. data/test/manual/banner-tests/test24.html +90 -26
  189. data/test/manual/banner-tests/test25.html +89 -25
  190. data/test/manual/banner_environment.rb +15 -2
  191. data/test/manual/codemirror_demo.html +773 -0
  192. data/test/manual/create_posts_for_web.rb +114 -0
  193. data/test/manual/preview_manual_test.rb +129 -0
  194. data/test/manual/test_banner_features.rb +14 -14
  195. data/test/manual/test_banner_integration.rb +115 -0
  196. data/test/manual/test_banner_radial.rb +87 -0
  197. data/test/manual/test_syntax_highlighting.rb +60 -40
  198. data/test/support/preview_utils.rb +88 -0
  199. data/test/test_gem_assets.rb +48 -0
  200. data/test/test_helpers.rb +10 -0
  201. data/test/tui_editor_integration_test.rb +15 -15
  202. data/test/tui_integration_test.rb +687 -441
  203. data/test/unit/api.rb +757 -37
  204. data/test/unit/asset_management.rb +195 -221
  205. data/test/unit/backup_test.rb +451 -0
  206. data/test/unit/contract_test.rb +1 -23
  207. data/test/unit/core.rb +415 -61
  208. data/test/unit/deploy_config_test.rb +248 -0
  209. data/test/unit/deploy_test.rb +312 -21
  210. data/test/unit/edit_post_test.rb +168 -0
  211. data/test/unit/gem_asset_management.rb +36 -42
  212. data/test/unit/livetext_basic.rb +23 -35
  213. data/test/unit/livetext_compatibility.rb +7 -14
  214. data/test/unit/parse_cmd_test.rb +260 -0
  215. data/test/unit/{symlink_test.rb → permalink_copy_test.rb} +47 -49
  216. data/test/unit/post.rb +91 -26
  217. data/test/unit/post_index_config_test.rb +258 -0
  218. data/test/unit/post_state_helpers_test.rb +137 -0
  219. data/test/unit/read_commented_file_test.rb +8 -6
  220. data/test/unit/repo.rb +75 -54
  221. data/test/unit/social_test.rb +41 -44
  222. data/test/unit/syntax_highlighting.rb +70 -0
  223. data/test/unit/theme_management_test.rb +91 -0
  224. data/test/unit/view.rb +79 -12
  225. data/test/unit/widgets.rb +8 -8
  226. data/test/web_integration_test.rb +231 -0
  227. data/test/web_test_helper.rb +218 -0
  228. data/test/web_workflow_test.rb +527 -0
  229. data/ui/tui/bin/scriptorium +885 -415
  230. data/ui/web/app/app.rb +1398 -176
  231. data/ui/web/app/assets/livetext_mode.js +244 -0
  232. data/ui/web/app/error_helpers.rb +16 -16
  233. data/ui/web/app/views/advanced_config.erb +8 -2
  234. data/ui/web/app/views/asset_management.erb +56 -0
  235. data/ui/web/app/views/backup_management.erb +238 -0
  236. data/ui/web/app/views/config_widget.erb +232 -0
  237. data/ui/web/app/views/dashboard.erb +64 -72
  238. data/ui/web/app/views/deploy_config.erb +3 -0
  239. data/ui/web/app/views/edit_pages.erb +170 -2
  240. data/ui/web/app/views/edit_post.erb +130 -9
  241. data/ui/web/app/views/edit_theme.erb +73 -0
  242. data/ui/web/app/views/edit_theme_file.erb +74 -0
  243. data/ui/web/app/views/theme_management.erb +130 -0
  244. data/ui/web/app/views/view_dashboard.erb +666 -25
  245. data/ui/web/app/views/widgets.erb +249 -0
  246. data/ui/web/bin/scriptorium-web +35 -24
  247. data/ui/web/tmp/timing.log +17 -0
  248. data/ui/web/tmp/web_server.log +0 -5
  249. metadata +190 -116
  250. data/assets/back-icon.png +0 -0
  251. data/assets/icons/facebook.svg +0 -1
  252. data/assets/icons/github.svg +0 -1
  253. data/assets/icons/instagram.svg +0 -1
  254. data/assets/icons/reddit.svg +0 -1
  255. data/assets/icons/x.svg +0 -1
  256. data/assets/icons/youtube.svg +0 -1
  257. data/bin/scriptorium +0 -1511
  258. data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +0 -34
  259. data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +0 -50
  260. data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +0 -73
  261. data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +0 -70
  262. data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +0 -110
  263. data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +0 -73
  264. data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +0 -124
  265. data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +0 -46
  266. data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +0 -97
  267. data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +0 -211
  268. data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +0 -141
  269. data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +0 -211
  270. data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +0 -134
  271. data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +0 -41
  272. data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +0 -49
  273. data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +0 -46
  274. data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +0 -41
  275. data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +0 -41
  276. data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +0 -256
  277. data/lib/scriptorium/syntax_highlighter.rb +0 -234
  278. data/test/manual/deploy_symlink_demo.rb +0 -142
  279. data/test/manual/symlink_demo.rb +0 -117
  280. data/test/manual/test2.rb +0 -12
  281. data/test/manual/test_banner_from_file.rb +0 -150
  282. data/test/manual/test_banner_in_header.rb +0 -35
  283. data/test/manual/test_code_highlighting.rb +0 -68
  284. data/test/manual/test_complex_header.rb +0 -74
  285. data/test/manual/test_empty_header.rb +0 -32
  286. data/test/manual/test_radial_custom.rb +0 -58
  287. data/test/manual/test_radial_large_radius.rb +0 -52
  288. data/test/manual/test_svg_debug.rb +0 -47
  289. data/test/pages-demo/config/currentview.txt +0 -1
  290. data/test/pages-demo/views/demo/config/common.js +0 -57
  291. data/test/pages-demo/views/demo/config/footer.txt +0 -1
  292. data/test/pages-demo/views/demo/config/global-head.txt +0 -8
  293. data/test/pages-demo/views/demo/config/header.txt +0 -1
  294. data/test/pages-demo/views/demo/config/layout.txt +0 -1
  295. data/test/pages-demo/views/demo/config/left.txt +0 -1
  296. data/test/pages-demo/views/demo/config/main.txt +0 -1
  297. data/test/pages-demo/views/demo/config/right.txt +0 -1
  298. data/test/pages-demo/views/demo/config.txt +0 -3
  299. data/test/pages-demo/views/demo/output/panes/footer.html +0 -1
  300. data/test/pages-demo/views/demo/output/panes/header.html +0 -1
  301. data/test/pages-demo/views/demo/output/panes/left.html +0 -1
  302. data/test/pages-demo/views/demo/output/panes/main.html +0 -1
  303. data/test/pages-demo/views/demo/output/panes/right.html +0 -1
  304. data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +0 -5
  305. data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +0 -4
  306. data/test/scriptorium-TEST-1754622690-146/config/common.js +0 -57
  307. data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +0 -1
  308. data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +0 -9
  309. data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +0 -1
  310. data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +0 -4
  311. data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +0 -3
  312. data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +0 -8
  313. data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +0 -6
  314. data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +0 -1
  315. data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +0 -1
  316. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +0 -1
  317. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +0 -1
  318. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +0 -14
  319. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +0 -13
  320. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +0 -1
  321. data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +0 -5
  322. data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +0 -4
  323. data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +0 -57
  324. data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +0 -5
  325. data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +0 -2
  326. data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +0 -9
  327. data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +0 -4
  328. data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +0 -5
  329. data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +0 -3
  330. data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +0 -5
  331. data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +0 -3
  332. data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +0 -7
  333. data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +0 -3
  334. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +0 -3
  335. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +0 -3
  336. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +0 -3
  337. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +0 -3
  338. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +0 -3
  339. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +0 -1
  340. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +0 -1
  341. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +0 -1
  342. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +0 -1
  343. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +0 -1
  344. data/ui/web/tmp/web_server.pid +0 -1
  345. /data/{test/pages-demo/views/demo/config/bootstrap_css.txt → lib/scriptorium/support/bootstrap/css.txt} +0 -0
  346. /data/{test/pages-demo/views/demo/config/bootstrap_js.txt → lib/scriptorium/support/bootstrap/js.txt} +0 -0
  347. /data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/reddit.txt +0 -0
  348. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout → lib/scriptorium/support/templates}/layout.txt +0 -0
  349. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt → lib/scriptorium/support/theme/footer.lt3} +0 -0
  350. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt → lib/scriptorium/support/theme/left.lt3} +0 -0
  351. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt → lib/scriptorium/support/theme/main.lt3} +0 -0
  352. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt → lib/scriptorium/support/theme/right.lt3} +0 -0
  353. /data/test/manual/banner-tests/{config.txt → svg.txt} +0 -0
  354. /data/test/manual/{test6.rb → test_advanced_widgets.rb} +0 -0
  355. /data/test/manual/{test1.rb → test_basic_posts.rb} +0 -0
  356. /data/test/manual/{test4.rb → test_layout_widgets.rb} +0 -0
  357. /data/test/manual/{test5.rb → test_pagination.rb} +0 -0
  358. /data/test/manual/{test3.rb → test_random_posts.rb} +0 -0
@@ -0,0 +1,106 @@
1
+ .h1 An 'in' operator for Ruby
2
+
3
+ .set post.num = 0016
4
+ .set post.slug = an-in-operator-for-ruby
5
+ .set post.date = 2019-11-13
6
+ .set post.title = An 'in' operator for Ruby
7
+ .set post.tags =
8
+ .set post.views = computing
9
+ .set post.published = yes
10
+ .set post.deployed = no
11
+
12
+ I have had two fairly small changes I wanted to make in Ruby. The first
13
+ was realized years ago.
14
+ Hashes now preserve insertion order and iterate in a predictable way.
15
+ That's fairly minor, but it did/does have some use cases, and it had no impact
16
+ on performance.
17
+
18
+ Here's another one. Personally, this is a bigger thing to me.
19
+
20
+ I've always believed personally that Ruby should have an in operator.
21
+
22
+ I've mentioned this in speaking (including lightning talks) and in writing.
23
+ It's not a giant big deal for me, but it is one of my personal favorite ideas.
24
+ Here are some details.
25
+
26
+ My proposal
27
+
28
+ I propose to let x in y be syntax sugar for y.include? x
29
+
30
+ You may ask: Why?
31
+
32
+ include? is backwards from common usage -- if the item is our focus, we don't ask whether a group includes an item, but whether an item is in a group. The same is true of a container.
33
+
34
+ Ruby isn't English; and more generally, programming languages aren't human languages. But programming languages are based on human languages and on everyday experience. We do sometimes ask questions like "Does this container or group include this item?" We are asking a question about the group. if barrel.include? rotten_apple # Is barrel going bad?
35
+
36
+ But we also -- perhaps more often? -- ask questions like "Is this item part of this group?" We are asking a question about the item. if fruit in [:apple, :pear, :peach] # Is this fruit something I like?
37
+
38
+ include? is backwards from mathematical usage -- we ask whether a member is in a set ("epsilon"-like notation), not whether a set contains a memeber.
39
+
40
+ I ran across someone else a couple of years ago (I wish I could remember who it was!) who bemoaned the absence of this operator. His argument was that he would have a "conversation" with an object, for example, when he tested it repeatedly. Here's a contrived example I just made up.
41
+
42
+ [" if foo == var1 ||", " foo =~ var2 ||", " foo var5]"]
43
+
44
+ To quote him as well as I remember: "I was having this perfectly nice conversation
45
+ with foo, and then var4 interrupted it..."
46
+
47
+ Better:
48
+
49
+ [" if foo == var1 ||", " foo =~ var2 ||", " foo var5]"]
50
+
51
+ I prefer to put the tested entity earlier in the statement:
52
+
53
+ [" if [GA, VA, MS, TX, MD, NC].include? state # ehhhh", " if state in [GA, VA, MS, TX, MD, NC] # better"]
54
+
55
+ Also a "variable/constant" issue -- I tend to put the variable data on the
56
+ left and the constant on right; this is unlike people who say if 5 == x.
57
+ (After all, 5 is only equal to x very rarely; 5 is always equal to 5,
58
+ even for very large values of 5.)
59
+
60
+ Also a question of focus: Whatever entity you are really dealing with,
61
+ name that one first.
62
+
63
+ Many languages already have an in operator -- notably Python, Pascal,
64
+ even SQL. It is familiar to users of those languages as well as those
65
+ who use mathematical notation.
66
+
67
+ in is already a reserved word in Ruby -- used in the for loop (syntax
68
+ sugar for each). Let's increase the justification for its presence.
69
+
70
+ An in operator would sometimes make parentheses unnecessary:
71
+
72
+ [" if (10..100).include? x # Need parens", " if x in 10..100 # Don't need parens -- also prettier code"]
73
+
74
+ The newer language Elixir (which I'm happy to report occupies a lot of my
75
+ time lately) also sports this operator. This is yet another reason to
76
+ love that language.
77
+
78
+ Frequently Whined Whines
79
+
80
+ I'd prefer a method. I understand this, but I find it to be
81
+ needlessly ugly. I like less punctuation, more whitespace. And I
82
+ find this inappropriate for something that is conceptually an operator.
83
+
84
+ [" if x.in mylist # ugly ", " if x.== 5 # also ugly ", " if c1.and c2 # ugly - if it worked ", " if x == 5 # better ", " if c1 and c2 # better ", " if x in mylist # better"]
85
+
86
+ I'd prefer a method with a ? on it. I understand
87
+ the concept, too, but I find it inappropriate for what is inherently a relational operator.
88
+
89
+ [" if x.in? my_set # very ugly ", " if x.==? 5 # very ugly - if it worked", "", " if x in my_set # natural", " if x == 5 # natural"]
90
+
91
+ What about for x in list ? Would this evaluate as
92
+ for true or for false ? Certainly not. It's a matter
93
+ of parsing. The for loop itself is just syntax sugar.
94
+
95
+ I'll bet you like junctions, too. No, in fact, I dislike junctions greatly. I don't even know Perl. Are junctions still a thing?
96
+
97
+ If you like SQL's in , you must like not in also. No, I don't condone its use of "not in":
98
+
99
+ if item not in collection # travesty! if ! (item in collection) # ok
100
+
101
+ if x not == y # horrible Ruby travesty - if it worked Yes, I say this even though ! ( item in collection) requires parentheses. See the comment about parentheses on ranges.
102
+
103
+ What about precedence? I would place in at the same level of precedence as the (other) relational operators = etc.Conclusion
104
+
105
+ People have ignored me on this for at least ten years. They probably still will.
106
+ That, as they say, is life.
@@ -0,0 +1,7 @@
1
+ num 0017
2
+ title The Forgotten Mathematician
3
+ date 2019-12-25
4
+ pubdate 2019-12-25
5
+ views computing
6
+ tags
7
+ pinned
@@ -0,0 +1,161 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>The Forgotten Mathematician</title>
6
+ <meta name="generator" content="Scriptorium Import">
7
+ <meta property="og:title" content="The Forgotten Mathematician">
8
+ <meta property="og:locale" content="en_US">
9
+ <meta property="og:type" content="article">
10
+ <meta property="article:published_time" content="2019-12-25">
11
+ </head>
12
+ <body>
13
+ <article>
14
+ <header>
15
+ <h1>The Forgotten Mathematician</h1>
16
+ <time datetime="2019-12-25">December 25, 2019</time>
17
+ </header>
18
+
19
+ <div class="content">
20
+ <p>
21
+ We all know his name... but many of us only "sort of" know it.
22
+
23
+ <div class='mydrop'>W</div>
24
+ <div style="padding-top: 1px">e all remember Boole in our own way, if at all. His work comes up in discrete
25
+ math and in electrical engineering, among other places. But computer science students and
26
+ programmers in general remember him chiefly for the Boolean operators and the concept of the
27
+ Boolean data type.
28
+
29
+ <p>
30
+ I decided to Google for "who was Boole"... this was the result.
31
+
32
+ <p>
33
+ <img src='gooboo.png'></img>
34
+
35
+ <p>
36
+
37
+ <p>
38
+ Notice the top autocomplete. This seems to suggest that "Boolean" was the person's name. I
39
+ decided to make this blog post to set the record straight.
40
+
41
+ <p>
42
+ But that isn't the only reason I'm writing this. I want to speak up for this historical figure
43
+ just a little and correct what I perceive as a minor injustice.
44
+
45
+ <p>
46
+ Did anything look unusual in the previous sentences? Perhaps the capitalization of "Boolean"?
47
+ It's often lowercased in the computing community, and there are reasonable historical reasons
48
+ for this.
49
+
50
+ <p>
51
+ In the old days, it was often inconvenient or impossible to type or even to render lowercase
52
+ letters. As recently as the 1980s, I have seen terminals and printers that were strictly uppercase.
53
+ Take a look at a textbook or manual from that era, and you will often see the same thing.
54
+
55
+ <p>
56
+ On the other hand, people have always known that in English and similar languages, lowercase was
57
+ an essential part of reality. As it became practical to use computers for applications such as
58
+ typesetting and word processing, we started to take mixed case for granted.
59
+
60
+ <p>
61
+ Somewhere in this time frame (or a little earlier), UNIX came along. And yes, we did spell it
62
+ in all caps at the time. This was true of most computer language names and such, many of which
63
+ were some kind of acronym or abbreviation: FORTRAN, COBOL, BASIC. There was no particular reason
64
+ to put PASCAL in all caps... but people often did, out of a strange kind of habit.
65
+
66
+ <p>
67
+ But let's get back to UNIX. Have you ever wondered why we type <font size=+1><tt>ls</tt></font>, <font size=+1><tt>cp</tt></font>, and <font size=+1><tt>mv</tt></font> rather than
68
+ <font size=+1><tt>list</tt></font>, <font size=+1><tt>copy</tt></font>, and <font size=+1><tt>move</tt></font>? It's not just that old terminals could be slow to echo. One of the
69
+ UNIX creators basically <i>hated to type</i>. (I remember it as Brian Kernighan, but it may have been
70
+ Thompson or Ritchie.) And I argue this laziness also extended to a reluctance to type capital letters.
71
+ Can you think of a command flag that is capitalized (such as <font size=+1><tt>-F</tt></font>) <i>except</i> where the lowercase
72
+ (such as <font size=+1><tt>-f</tt></font>) was already used by something more fundamental? I can't think of one.
73
+
74
+ <p>
75
+ So as we made a transition from all-caps to mixed case, programming languages that were traditionally
76
+ written in upper case were now written in all lower case. In Pascal, we might once have written
77
+ <font size=+1><tt>FOR I:=1 TO 10</tt></font>, but a little later, we wrote <font size=+1><tt>for i:=1 to 10</tt></font> instead.
78
+
79
+ <p>
80
+ Do you see where this is going? Where we once wrote <font size=+1><tt>BOOLEAN</tt></font>, we wrote <font size=+1><tt>boolean</tt></font> instead. And
81
+ because we saw this so often in our programs, we started writing it that way when we wrote <i>about</i>
82
+ our programs.
83
+
84
+ <p>
85
+ Sometimes this is necessary. If you are using a language where identifiers are case-sensitive (like
86
+ most or all modern languages), there may well be an actual data type named <font size=+1><tt>boolean</tt></font>, and it would
87
+ be an error to capitalize it (even outside our code).
88
+
89
+ <p>
90
+ So typography matters here. For many years we have tended to write code in some kind of monospaced
91
+ typeface, harking back to the days when we had no choice in the matter. So consider these three
92
+ sentences, which might appear in any manual or piece of documentation:
93
+
94
+ <p>
95
+ <ol>
96
+ <li>This function takes a <font size=+1><tt>boolean</tt></font> parameter.</li>
97
+ <li>This function takes a boolean parameter.</li>
98
+ <li>This function takes a Boolean parameter.</li>
99
+ </ol>
100
+ It's reasonable to use lowercase in (1), because we're presumably referring to an actual identifier
101
+ or reserved word in some language. As for (2) &mdash; I think we see that all the time, but I'm arguing
102
+ here it's not appropriate. The usage in (3) is more appropriate.
103
+
104
+ <p>
105
+ Now, before I am misunderstood and/or flamed &mdash; here are the things I am <i>not</i> saying:
106
+
107
+ <p>
108
+ <ul>
109
+ <li> I'm not saying we should change the compilers or interpreters.</li>
110
+ <li> I'm not saying that all the books and manuals should be rewritten.</li>
111
+ <li> I'm not saying you're ignorant or a bad person if you don't capitalize "Boolean."</li>
112
+ <li> I'm not saying we should call out people who don't capitalize it.</li>
113
+ </ul>
114
+ But for comparison, let's look at some other scientists and mathematicians whose names have been
115
+ converted to adjectives. So far I have searched for these: Einsteinian, Newtonian, Galilean,
116
+ Ptolemaic, Copernican, Wronskian, Laplacian, Lagrangian, Riemannian, Euclidean, Keplerian,
117
+ Gaussian, Hamiltonian, Archimedean, Diophantine, Pythagorean, Darwinian, Lamarckian, Eulerian,
118
+ Cartesian, Napierian, Bayesian, and Brownian.
119
+
120
+ <p>
121
+ These terms have this in common: They are <i>always capitalized</i>. (Interestingly, <i>Abelian</i> seems
122
+ to be an exception in many people's usage.) And yes, you may find places where these names are
123
+ <i>not</i> given capital letters, but I contend they are very few in number.
124
+
125
+ <p>
126
+ Let's range further afield, into the realms of philosophers, religious figures, writers, and
127
+ artists. I have searched for these: Socratic, Aristotelian, Mosaic, Benedictine, Kafkaesque,
128
+ Epicurean, Shakespearean, Elizabethan, Edwardian, Spenserian, Petrarchan, Smithsonian, Botticellian,
129
+ Dickensian, Orwellian, Jungian, Freudian, and Adlerian. I've found very few uncapitalized
130
+ names. The lowercased <i>kafkaesque</i> is not unheard of, and we may informally call someone an
131
+ <i>epicurean</i> (though we refer specifically to the <i>Epicurean</i> philosophers in uppercase).
132
+
133
+ <p>
134
+ It's worth noting that units of measure named after people are not capitalized:
135
+ newton, ampere, coulomb, gauss, fermi, kelvin, henry, hertz, pascal, and watt. I can't find an
136
+ exception to this. Sometimes, though, the person's name is tacked on as <i>part</i> of the unit or
137
+ system of measure; we do capitalize the names when we refer to degrees Fahrenheit, degrees
138
+ Celsius, Richter scale, Mohs scale, and the Dobson unit.
139
+
140
+ <p>
141
+ Of course, in many cases, we just don't convert a name to a different form: Hilbert space,
142
+ Schwarzschild radius, Feynmann diagram, Bohr model, Fermi principle, Drake equation, Rohrschach
143
+ test, Hall effect, and so on. Why is this so common? I think it's because an adjective form
144
+ might often be hard to spell or pronounce, and overall we have less of a tendency for "fancy"
145
+ adjectives nowadays. But in any event, we'd never think of lowercasing these names.
146
+
147
+ <p>
148
+ And yet Boole is shortchanged so often in our world! Mathematicians talk about Boolean algebra,
149
+ and even electrical engineers talk of Boolean logic; but programmers talk of <i>boolean</i> data and
150
+ <i>boolean</i> operators.
151
+
152
+ <p>
153
+ Come on, guys. Give him his due. By the way, his first name was George.
154
+
155
+ <p>
156
+ So I am making a pledge: Where it's possible and practical, I will capitalize <i>Boolean</i> whenever
157
+ I write an article, a book, or a piece of documentation. I encourage you to do the same.
158
+ </div>
159
+ </article>
160
+ </body>
161
+ </html>
@@ -0,0 +1,119 @@
1
+ .h1 The Forgotten Mathematician
2
+
3
+ .set post.num = 0017
4
+ .set post.slug = the-forgotten-mathematician
5
+ .set post.date = 2019-12-25
6
+ .set post.title = The Forgotten Mathematician
7
+ .set post.tags =
8
+ .set post.views = computing
9
+ .set post.published = yes
10
+ .set post.deployed = no
11
+
12
+ We all know his name... but many of us only "sort of" know it.
13
+
14
+ W
15
+ e all remember Boole in our own way, if at all. His work comes up in discrete
16
+ math and in electrical engineering, among other places. But computer science students and
17
+ programmers in general remember him chiefly for the Boolean operators and the concept of the
18
+ Boolean data type.
19
+
20
+ I decided to Google for "who was Boole"... this was the result.
21
+
22
+ Notice the top autocomplete. This seems to suggest that "Boolean" was the person's name. I
23
+ decided to make this blog post to set the record straight.
24
+
25
+ But that isn't the only reason I'm writing this. I want to speak up for this historical figure
26
+ just a little and correct what I perceive as a minor injustice.
27
+
28
+ Did anything look unusual in the previous sentences? Perhaps the capitalization of "Boolean"?
29
+ It's often lowercased in the computing community, and there are reasonable historical reasons
30
+ for this.
31
+
32
+ In the old days, it was often inconvenient or impossible to type or even to render lowercase
33
+ letters. As recently as the 1980s, I have seen terminals and printers that were strictly uppercase.
34
+ Take a look at a textbook or manual from that era, and you will often see the same thing.
35
+
36
+ On the other hand, people have always known that in English and similar languages, lowercase was
37
+ an essential part of reality. As it became practical to use computers for applications such as
38
+ typesetting and word processing, we started to take mixed case for granted.
39
+
40
+ Somewhere in this time frame (or a little earlier), UNIX came along. And yes, we did spell it
41
+ in all caps at the time. This was true of most computer language names and such, many of which
42
+ were some kind of acronym or abbreviation: FORTRAN, COBOL, BASIC. There was no particular reason
43
+ to put PASCAL in all caps... but people often did, out of a strange kind of habit.
44
+
45
+ But let's get back to UNIX. Have you ever wondered why we type ls, cp, and mv rather than
46
+ list, copy, and move? It's not just that old terminals could be slow to echo. One of the
47
+ UNIX creators basically hated to type. (I remember it as Brian Kernighan, but it may have been
48
+ Thompson or Ritchie.) And I argue this laziness also extended to a reluctance to type capital letters.
49
+ Can you think of a command flag that is capitalized (such as -F) except where the lowercase
50
+ (such as -f) was already used by something more fundamental? I can't think of one.
51
+
52
+ So as we made a transition from all-caps to mixed case, programming languages that were traditionally
53
+ written in upper case were now written in all lower case. In Pascal, we might once have written
54
+ FOR I:=1 TO 10, but a little later, we wrote for i:=1 to 10 instead.
55
+
56
+ Do you see where this is going? Where we once wrote BOOLEAN, we wrote boolean instead. And
57
+ because we saw this so often in our programs, we started writing it that way when we wrote about
58
+ our programs.
59
+
60
+ Sometimes this is necessary. If you are using a language where identifiers are case-sensitive (like
61
+ most or all modern languages), there may well be an actual data type named boolean, and it would
62
+ be an error to capitalize it (even outside our code).
63
+
64
+ So typography matters here. For many years we have tended to write code in some kind of monospaced
65
+ typeface, harking back to the days when we had no choice in the matter. So consider these three
66
+ sentences, which might appear in any manual or piece of documentation:
67
+
68
+ This function takes a boolean parameter.
69
+ This function takes a boolean parameter.
70
+ This function takes a Boolean parameter.
71
+
72
+ It's reasonable to use lowercase in (1), because we're presumably referring to an actual identifier
73
+ or reserved word in some language. As for (2) &mdash; I think we see that all the time, but I'm arguing
74
+ here it's not appropriate. The usage in (3) is more appropriate.
75
+
76
+ Now, before I am misunderstood and/or flamed &mdash; here are the things I am not saying:
77
+
78
+ I'm not saying we should change the compilers or interpreters.
79
+ I'm not saying that all the books and manuals should be rewritten.
80
+ I'm not saying you're ignorant or a bad person if you don't capitalize "Boolean."
81
+ I'm not saying we should call out people who don't capitalize it.
82
+
83
+ But for comparison, let's look at some other scientists and mathematicians whose names have been
84
+ converted to adjectives. So far I have searched for these: Einsteinian, Newtonian, Galilean,
85
+ Ptolemaic, Copernican, Wronskian, Laplacian, Lagrangian, Riemannian, Euclidean, Keplerian,
86
+ Gaussian, Hamiltonian, Archimedean, Diophantine, Pythagorean, Darwinian, Lamarckian, Eulerian,
87
+ Cartesian, Napierian, Bayesian, and Brownian.
88
+
89
+ These terms have this in common: They are always capitalized. (Interestingly, Abelian seems
90
+ to be an exception in many people's usage.) And yes, you may find places where these names are
91
+ not given capital letters, but I contend they are very few in number.
92
+
93
+ Let's range further afield, into the realms of philosophers, religious figures, writers, and
94
+ artists. I have searched for these: Socratic, Aristotelian, Mosaic, Benedictine, Kafkaesque,
95
+ Epicurean, Shakespearean, Elizabethan, Edwardian, Spenserian, Petrarchan, Smithsonian, Botticellian,
96
+ Dickensian, Orwellian, Jungian, Freudian, and Adlerian. I've found very few uncapitalized
97
+ names. The lowercased kafkaesque is not unheard of, and we may informally call someone an
98
+ epicurean (though we refer specifically to the Epicurean philosophers in uppercase).
99
+
100
+ It's worth noting that units of measure named after people are not capitalized:
101
+ newton, ampere, coulomb, gauss, fermi, kelvin, henry, hertz, pascal, and watt. I can't find an
102
+ exception to this. Sometimes, though, the person's name is tacked on as part of the unit or
103
+ system of measure; we do capitalize the names when we refer to degrees Fahrenheit, degrees
104
+ Celsius, Richter scale, Mohs scale, and the Dobson unit.
105
+
106
+ Of course, in many cases, we just don't convert a name to a different form: Hilbert space,
107
+ Schwarzschild radius, Feynmann diagram, Bohr model, Fermi principle, Drake equation, Rohrschach
108
+ test, Hall effect, and so on. Why is this so common? I think it's because an adjective form
109
+ might often be hard to spell or pronounce, and overall we have less of a tendency for "fancy"
110
+ adjectives nowadays. But in any event, we'd never think of lowercasing these names.
111
+
112
+ And yet Boole is shortchanged so often in our world! Mathematicians talk about Boolean algebra,
113
+ and even electrical engineers talk of Boolean logic; but programmers talk of boolean data and
114
+ boolean operators.
115
+
116
+ Come on, guys. Give him his due. By the way, his first name was George.
117
+
118
+ So I am making a pledge: Where it's possible and practical, I will capitalize Boolean whenever
119
+ I write an article, a book, or a piece of documentation. I encourage you to do the same.
@@ -0,0 +1,7 @@
1
+ num 0018
2
+ title Ruby puns
3
+ date 2020-01-21
4
+ pubdate 2020-01-21
5
+ views computing computing
6
+ tags
7
+ pinned
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Ruby puns</title>
6
+ <meta name="generator" content="Scriptorium Import">
7
+ <meta property="og:title" content="Ruby puns">
8
+ <meta property="og:locale" content="en_US">
9
+ <meta property="og:type" content="article">
10
+ <meta property="article:published_time" content="2020-01-21">
11
+ </head>
12
+ <body>
13
+ <article>
14
+ <header>
15
+ <h1>Ruby puns</h1>
16
+ <time datetime="2020-01-21">January 21, 2020</time>
17
+ </header>
18
+
19
+ <div class="content">
20
+ <p>
21
+ These are pretty bad. You've been warned.
22
+
23
+ <p>
24
+ <pre>
25
+ cheese = "" # String cheese
26
+ browns = {} # Hash browns
27
+ hiphip = [] # hiphip array
28
+ case; end # brief case
29
+ foods.freeze # frozen foods
30
+ love.taint # tainted love
31
+ attr_writer :irish # Irish setter
32
+ {"corned" => "beef"} # corned beef hash
33
+ raise "hell" # raising hell
34
+ $village # global village
35
+
36
+ usual_suspects = 1.99
37
+ usual_suspects.ceil # round up the usual suspects
38
+
39
+ class JesusChrist < God
40
+ super(*) # Jesus Christ Superstar
41
+ end
42
+ </pre>
43
+ </div>
44
+ </article>
45
+ </body>
46
+ </html>
@@ -0,0 +1,28 @@
1
+ .h1 Ruby puns
2
+
3
+ .set post.num = 0018
4
+ .set post.slug = ruby-puns
5
+ .set post.date = 2020-01-21
6
+ .set post.title = Ruby puns
7
+ .set post.tags =
8
+ .set post.views = computing computing
9
+ .set post.published = yes
10
+ .set post.deployed = no
11
+
12
+ These are pretty bad. You've been warned.
13
+
14
+ cheese = "" # String cheese
15
+ browns = {} # Hash browns
16
+ hiphip = [] # hiphip array
17
+ case; end # brief case
18
+ foods.freeze # frozen foods
19
+ love.taint # tainted love
20
+ attr_writer :irish # Irish setter
21
+ {"corned" => "beef"} # corned beef hash
22
+ raise "hell" # raising hell
23
+ $village # global village
24
+
25
+ usual_suspects = 1.99
26
+ usual_suspects.ceil # round up the usual suspects
27
+
28
+ class JesusChrist
@@ -0,0 +1,7 @@
1
+ num 0019
2
+ title Custom exceptions via metaprogramming
3
+ date 2020-02-17
4
+ pubdate 2020-02-17
5
+ views computing computing
6
+ tags
7
+ pinned
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Custom exceptions via metaprogramming</title>
6
+ <meta name="generator" content="Scriptorium Import">
7
+ <meta property="og:title" content="Custom exceptions via metaprogramming">
8
+ <meta property="og:locale" content="en_US">
9
+ <meta property="og:type" content="article">
10
+ <meta property="article:published_time" content="2020-02-17">
11
+ </head>
12
+ <body>
13
+ <article>
14
+ <header>
15
+ <h1>Custom exceptions via metaprogramming</h1>
16
+ <time datetime="2020-02-17">February 17, 2020</time>
17
+ </header>
18
+
19
+ <div class="content">
20
+ <p>
21
+ Suppose you want a large number of custom exceptions. And suppose you're not afraid of metaprogramming.
22
+ A few months back, I found myself wanting to be "more specific" with the exceptions
23
+ I raised in my ongoing RuneBlog project (which is used to create this blog). I
24
+ wanted to raise specific exceptions with custom parameterized messages (without
25
+ repeating myself too much).
26
+
27
+ <p>
28
+ Here's an example of the "usual" way to do this:
29
+
30
+ <p>
31
+ <div class="highlight">
32
+ <span class="k">class</span> <span class="nc">MyException</span> <span class="o">&lt;</span> <span class="no">StandardError</span>
33
+
34
+ <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">dir</span><span class="p">)</span>
35
+ <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Could not find </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2"> under </span><span class="si">#{</span><span class="n">dir</span><span class="si">}</span><span class="s2">"</span>
36
+ <span class="k">super</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
37
+ <span class="k">end</span>
38
+
39
+ <span class="k">end</span>
40
+
41
+ <span class="k">raise</span> <span class="no">MyException</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"stuff.txt"</span><span class="p">,</span> <span class="s2">"/home/willard"</span><span class="p">)</span>
42
+
43
+ <span class="c1"># Output:</span>
44
+ <span class="c1"># exc.rb:10:in `&lt;main&gt;': Could not find stuff.txt under /home/willard (MyException)</span>
45
+ </div>
46
+ <br>
47
+ Now there is nothing particularly wrong with that. But as it happens, I wanted a
48
+ large number of exceptions with fairly descriptive names. I didn't want to type
49
+ (or even paste) this stuff over and over.
50
+
51
+ <p>
52
+ Here comes the "not afraid of metaprogramming" part. This is what I did:
53
+
54
+ <p>
55
+ <div class="highlight">
56
+ <span class="k">def</span> <span class="nf">make_exception</span><span class="p">(</span><span class="n">sym</span><span class="p">,</span> <span class="n">str</span><span class="p">,</span> <span class="n">target_class</span> <span class="o">=</span> <span class="no">Object</span><span class="p">)</span>
57
+ <span class="k">return</span> <span class="k">if</span> <span class="n">target_class</span><span class="p">.</span><span class="nf">constants</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="n">sym</span><span class="p">)</span>
58
+ <span class="n">target_class</span><span class="p">.</span><span class="nf">const_set</span><span class="p">(</span><span class="n">sym</span><span class="p">,</span> <span class="no">StandardError</span><span class="p">.</span><span class="nf">dup</span><span class="p">)</span>
59
+ <span class="n">define_method</span><span class="p">(</span><span class="n">sym</span><span class="p">)</span> <span class="k">do</span> <span class="o">|*</span><span class="n">args</span><span class="o">|</span>
60
+ <span class="n">msg</span> <span class="o">=</span> <span class="n">str</span><span class="p">.</span><span class="nf">dup</span>
61
+ <span class="n">args</span><span class="p">.</span><span class="nf">each</span><span class="p">.</span><span class="nf">with_index</span> <span class="p">{</span><span class="o">|</span><span class="n">arg</span><span class="p">,</span> <span class="n">i</span><span class="o">|</span> <span class="n">msg</span><span class="p">.</span><span class="nf">sub!</span><span class="p">(</span><span class="s2">"%</span><span class="si">#{</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span> <span class="p">}</span>
62
+ <span class="n">target_class</span><span class="p">.</span><span class="nf">class_eval</span><span class="p">(</span><span class="n">sym</span><span class="p">.</span><span class="nf">to_s</span><span class="p">).</span><span class="nf">new</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
63
+ <span class="k">end</span>
64
+ <span class="k">end</span>
65
+ </div>
66
+ <br>
67
+ Now, what does this do? The method takes two parameters (or three if you count the
68
+ target class which defaults to <font size=+1><tt>Object</tt></font>). You specify a symbol (for the
69
+ name of the exception) and a string (for the exception message). It then does
70
+ two things: It creates an exception class (named after the symbol); and it creates
71
+ a method of the same name.
72
+
73
+ <p>
74
+ Here are examples of calling <font size=+1><tt>make_exception</tt></font>:
75
+
76
+ <p>
77
+ <div class="highlight">
78
+ <span class="n">make_exception</span><span class="p">(</span><span class="ss">:NotImplemented</span><span class="p">,</span> <span class="s2">"Feature not yet implemented"</span><span class="p">)</span>
79
+ <span class="n">make_exception</span><span class="p">(</span><span class="ss">:CantOpen</span><span class="p">,</span> <span class="s2">"Can't open '%1'"</span><span class="p">)</span>
80
+ <span class="n">make_exception</span><span class="p">(</span><span class="ss">:InternalError</span><span class="p">,</span> <span class="s2">"Internal error: Method %1 got arg '%2'"</span><span class="p">)</span>
81
+ </div>
82
+ <br>
83
+ And here are examples of raising these exceptions:
84
+
85
+ <p>
86
+ <div class="highlight">
87
+ <span class="k">raise</span> <span class="no">NotImplemented</span>
88
+ <span class="k">raise</span> <span class="no">CantOpen</span><span class="p">(</span><span class="n">somefile</span><span class="p">)</span>
89
+ <span class="k">raise</span> <span class="no">InternalError</span><span class="p">(</span><span class="n">__method__</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
90
+ </div>
91
+ <br>
92
+ You might ask: Why define a method returning an exception object? The answer
93
+ is that I don't want to write these this way:
94
+
95
+ <p>
96
+ <div class="highlight">
97
+ <span class="k">raise</span> <span class="no">NotImplemented</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Feature not yet implemented"</span><span class="p">)</span>
98
+ <span class="k">raise</span> <span class="no">CantOpen</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Can't open '</span><span class="si">#{</span><span class="n">somefile</span><span class="si">}</span><span class="s2">'"</span><span class="p">)</span>
99
+ <span class="k">raise</span> <span class="no">InternalError</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Internal error: Method </span><span class="si">#{</span><span class="n">__method__</span><span class="si">}</span><span class="s2"> got arg '</span><span class="si">#{</span><span class="n">arg</span><span class="si">}</span><span class="s2">'"</span><span class="p">)</span>
100
+ </div>
101
+ <br>
102
+ I perceive four advantages doing it the first way: I don't have to specify the
103
+ message string each time; I still get to have a descriptive, unique class name
104
+ without the message making it seem redundantly; I don't have to interpolate
105
+ values into the message string explicitly; and I don't have to say <font size=+1><tt>.new</tt></font>
106
+ every time.
107
+
108
+ <p>
109
+ Some of you may have two questions: Can you (or should you) really have a
110
+ capitalized method name? Can a method have the same name as a class without
111
+ confusing the interpreter?
112
+
113
+ <p>
114
+ I'll answer both those questions with an example from the Ruby core: There
115
+ is an <font size=+1><tt>Integer</tt></font> class and an <font size=+1><tt>Integer</tt></font> method (naturally related to each other).
116
+ Ruby distinguishes between these by context. It's not impossible, and I argue
117
+ it's not a bad practice.
118
+
119
+ <p>
120
+ As for the parameters, it's intuitive how they work. A <font size=+1><tt>%</tt></font> sign signals a
121
+ numbered replaceable piece of text, and these are replaced with the parameters
122
+ specified when the method is called.
123
+
124
+ <p>
125
+ That part of the code is not really robust, by the way. As it is written now,you could easily confuse it-- make it misbehave or crash. But you get the idea.
126
+
127
+ <p>
128
+ So far, I have defined 23 custom exceptions in this project. Each definition
129
+ occupies a single line. If I want to change the behavior of all of them in
130
+ some way, I will go and change the <font size=+1><tt>make_exception</tt></font> method (which itself is
131
+ only 9 lines).
132
+
133
+ <p>
134
+ Like it, hate it? Comments welcome.
135
+ </div>
136
+ </article>
137
+ </body>
138
+ </html>