scriptorium 0.0.3 → 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 (353) hide show
  1. checksums.yaml +4 -4
  2. data/README.lt3 +324 -0
  3. data/README.md +3155 -1
  4. data/assets/.DS_Store +0 -0
  5. data/assets/README.md +44 -0
  6. data/assets/icons/social/reddit.png +0 -0
  7. data/assets/icons/social/x-logo.png +0 -0
  8. data/assets/icons/ui/.DS_Store +0 -0
  9. data/assets/icons/ui/back.png +0 -0
  10. data/assets/icons/ui/copy.png +0 -0
  11. data/assets/icons/ui/down.png +0 -0
  12. data/assets/icons/ui/end.png +0 -0
  13. data/assets/icons/ui/exit.png +0 -0
  14. data/assets/icons/ui/foo +10 -0
  15. data/assets/icons/ui/home.png +0 -0
  16. data/assets/icons/ui/left.png +0 -0
  17. data/assets/icons/ui/next.png +0 -0
  18. data/assets/icons/ui/right.png +0 -0
  19. data/assets/icons/ui/start.png +0 -0
  20. data/assets/icons/ui/up.png +0 -0
  21. data/assets/imagenotfound.jpg +0 -0
  22. data/assets/samples/placeholder.svg +9 -0
  23. data/assets/themes/standard/favicon.svg +6 -0
  24. data/bin/sblog +84 -5
  25. data/bin/scriptorium +1 -0
  26. data/doc/README.txt +6 -0
  27. data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
  28. data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
  29. data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
  30. data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
  31. data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
  32. data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
  33. data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
  34. data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
  35. data/doc/anti-amnesia/20250807-213025.md +116 -0
  36. data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
  37. data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
  38. data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
  39. data/doc/banner_svg_config.md +114 -0
  40. data/doc/contrib.lt3 +8 -0
  41. data/doc/dependencies.md +281 -0
  42. data/doc/hacker.lt3 +5 -0
  43. data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
  44. data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
  45. data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
  46. data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
  47. data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
  48. data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
  49. data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
  50. data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
  51. data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
  52. data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
  53. data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
  54. data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
  55. data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
  56. data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
  57. data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
  58. data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
  59. data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
  60. data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
  61. data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
  62. data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
  63. data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
  64. data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
  65. data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
  66. data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
  67. data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
  68. data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
  69. data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
  70. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
  71. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
  72. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
  73. data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
  74. data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
  75. data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
  76. data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
  77. data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
  78. data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
  79. data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
  80. data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
  81. data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
  82. data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
  83. data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
  84. data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
  85. data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
  86. data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
  87. data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
  88. data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
  89. data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
  90. data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
  91. data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
  92. data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
  93. data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
  94. data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
  95. data/doc/imported/0018-ruby-puns/post.html +46 -0
  96. data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
  97. data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
  98. data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
  99. data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
  100. data/doc/imported/0020-fffff/metadata.txt +7 -0
  101. data/doc/imported/0020-fffff/post.html +24 -0
  102. data/doc/imported/0020-fffff/source.lt3 +12 -0
  103. data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
  104. data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
  105. data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
  106. data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
  107. data/doc/imported/0023-doctor-sleep/post.html +63 -0
  108. data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
  109. data/doc/imported/0024-just-a-test/metadata.txt +7 -0
  110. data/doc/imported/0024-just-a-test/post.html +24 -0
  111. data/doc/imported/0024-just-a-test/source.lt3 +12 -0
  112. data/doc/imported/import_summary.txt +98 -0
  113. data/doc/livetext-informal-spec.txt +65 -0
  114. data/doc/myuserdoc/ch-0.lt3 +31 -0
  115. data/doc/myuserdoc/ch-1.lt3 +37 -0
  116. data/doc/myuserdoc/ch-10.lt3 +22 -0
  117. data/doc/myuserdoc/ch-2.lt3 +37 -0
  118. data/doc/myuserdoc/ch-3.lt3 +19 -0
  119. data/doc/myuserdoc/ch-4.lt3 +43 -0
  120. data/doc/myuserdoc/ch-5.lt3 +22 -0
  121. data/doc/myuserdoc/ch-6.lt3 +19 -0
  122. data/doc/myuserdoc/ch-7.lt3 +16 -0
  123. data/doc/myuserdoc/ch-8.lt3 +13 -0
  124. data/doc/myuserdoc/ch-9.lt3 +19 -0
  125. data/doc/myuserdoc/tweak.rb +18 -0
  126. data/doc/myuserdoc/userdoc-toc.txt +88 -0
  127. data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
  128. data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
  129. data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
  130. data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
  131. data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
  132. data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
  133. data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
  134. data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
  135. data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
  136. data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
  137. data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
  138. data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
  139. data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
  140. data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
  141. data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
  142. data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
  143. data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
  144. data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
  145. data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
  146. data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
  147. data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
  148. data/doc/old-posts/0024-just-a-test.lt3 +12 -0
  149. data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
  150. data/doc/old-repo +1 -0
  151. data/doc/reddit_credentials_template.json +8 -0
  152. data/doc/reddit_integration.md +207 -0
  153. data/doc/user.lt3 +35 -0
  154. data/doc/user_guide_section_1.md +137 -0
  155. data/doc/user_guide_section_10.md +515 -0
  156. data/doc/user_guide_section_11.md +708 -0
  157. data/doc/user_guide_section_2.md +233 -0
  158. data/doc/user_guide_section_3.md +5 -0
  159. data/doc/user_guide_section_4.md +221 -0
  160. data/doc/user_guide_section_5.md +243 -0
  161. data/doc/user_guide_section_6.md +147 -0
  162. data/doc/user_guide_section_7.md +311 -0
  163. data/doc/user_guide_section_8.md +224 -0
  164. data/doc/user_guide_section_9.md +375 -0
  165. data/lib/rouge/lexers/livetext.rb +74 -0
  166. data/lib/scriptorium/api.rb +2373 -0
  167. data/lib/scriptorium/banner_svg.rb +729 -0
  168. data/lib/scriptorium/contract.rb +34 -0
  169. data/lib/scriptorium/exceptions.rb +201 -1
  170. data/lib/scriptorium/helpers.rb +675 -0
  171. data/lib/scriptorium/post.rb +259 -0
  172. data/lib/scriptorium/reddit.rb +83 -0
  173. data/lib/scriptorium/repo.rb +938 -0
  174. data/lib/scriptorium/standard_files.rb +149 -0
  175. data/lib/scriptorium/support/bootstrap/css.txt +5 -0
  176. data/lib/scriptorium/support/bootstrap/js.txt +4 -0
  177. data/lib/scriptorium/support/common_js/clipboard.js +35 -0
  178. data/lib/scriptorium/support/common_js/content-loader.js +187 -0
  179. data/lib/scriptorium/support/common_js/navigation.js +52 -0
  180. data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
  181. data/lib/scriptorium/support/config/reddit.txt +10 -0
  182. data/lib/scriptorium/support/config/reddit_template.txt +17 -0
  183. data/lib/scriptorium/support/config/social.txt +8 -0
  184. data/lib/scriptorium/support/highlight/css.txt +2 -0
  185. data/lib/scriptorium/support/highlight/custom.css +119 -0
  186. data/lib/scriptorium/support/highlight/js.txt +1 -0
  187. data/lib/scriptorium/support/post_index/config.txt +15 -0
  188. data/lib/scriptorium/support/post_index/style.css +55 -0
  189. data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
  190. data/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
  191. data/lib/scriptorium/support/templates/layout.txt +5 -0
  192. data/lib/scriptorium/support/templates/post.lt3 +104 -0
  193. data/lib/scriptorium/support/theme/footer.lt3 +2 -0
  194. data/lib/scriptorium/support/theme/header.lt3 +4 -0
  195. data/lib/scriptorium/support/theme/left.lt3 +3 -0
  196. data/lib/scriptorium/support/theme/main.lt3 +5 -0
  197. data/lib/scriptorium/support/theme/right.lt3 +3 -0
  198. data/lib/scriptorium/theme.rb +192 -0
  199. data/lib/scriptorium/version.rb +1 -1
  200. data/lib/scriptorium/view.rb +1021 -0
  201. data/lib/scriptorium/widgets/featured_posts.rb +149 -0
  202. data/lib/scriptorium/widgets/links.rb +112 -0
  203. data/lib/scriptorium/widgets/pages.rb +133 -0
  204. data/lib/scriptorium/widgets/widget.rb +133 -0
  205. data/lib/scriptorium.rb +38 -34
  206. data/lib/skeleton.rb +10 -1
  207. data/scriptorium.gemspec +17 -5
  208. data/test/README.md +69 -0
  209. data/test/WEB_INTEGRATION_README.md +196 -0
  210. data/test/all +83 -0
  211. data/test/api_demo.rb +99 -0
  212. data/test/assets/imagenotfound.jpg +0 -0
  213. data/test/assets/images/.DS_Store +0 -0
  214. data/test/assets/images/README.md +27 -0
  215. data/test/assets/images/odd_aspect.png +0 -0
  216. data/test/assets/images/perfect.png +0 -0
  217. data/test/assets/images/small.png +0 -0
  218. data/test/assets/images/tall.png +0 -0
  219. data/test/assets/images/very_tall.png +0 -0
  220. data/test/assets/images/very_wide.png +0 -0
  221. data/test/assets/images/wide.png +0 -0
  222. data/test/assets/testbanner.jpg +0 -0
  223. data/test/banner_svg/simple_helpers.rb +13 -0
  224. data/test/banner_svg/unit.rb +1000 -0
  225. data/test/config/deployment.txt +5 -0
  226. data/test/ed_test.rb +204 -0
  227. data/test/integration/cursor_banner_combinations.rb +193 -0
  228. data/test/integration/cursor_banner_features.rb +374 -0
  229. data/test/integration/integration_test.rb +326 -0
  230. data/test/integration/preview_flow_test.rb +94 -0
  231. data/test/livetext_plugin_test.rb +500 -0
  232. data/test/manual/asset_mgmt.rb +67 -0
  233. data/test/manual/banner-tests/index.html +45 -0
  234. data/test/manual/banner-tests/svg.txt +3 -0
  235. data/test/manual/banner-tests/test01.html +122 -0
  236. data/test/manual/banner-tests/test02.html +122 -0
  237. data/test/manual/banner-tests/test03.html +122 -0
  238. data/test/manual/banner-tests/test04.html +129 -0
  239. data/test/manual/banner-tests/test05.html +129 -0
  240. data/test/manual/banner-tests/test06.html +129 -0
  241. data/test/manual/banner-tests/test07.html +129 -0
  242. data/test/manual/banner-tests/test08.html +123 -0
  243. data/test/manual/banner-tests/test09.html +123 -0
  244. data/test/manual/banner-tests/test10.html +123 -0
  245. data/test/manual/banner-tests/test11.html +123 -0
  246. data/test/manual/banner-tests/test12.html +123 -0
  247. data/test/manual/banner-tests/test13.html +123 -0
  248. data/test/manual/banner-tests/test14.html +123 -0
  249. data/test/manual/banner-tests/test15.html +122 -0
  250. data/test/manual/banner-tests/test16.html +122 -0
  251. data/test/manual/banner-tests/test17.html +122 -0
  252. data/test/manual/banner-tests/test18.html +132 -0
  253. data/test/manual/banner-tests/test19.html +132 -0
  254. data/test/manual/banner-tests/test20.html +132 -0
  255. data/test/manual/banner-tests/test21.html +132 -0
  256. data/test/manual/banner-tests/test22.html +132 -0
  257. data/test/manual/banner-tests/test23.html +132 -0
  258. data/test/manual/banner-tests/test24.html +132 -0
  259. data/test/manual/banner-tests/test25.html +131 -0
  260. data/test/manual/banner_environment.rb +205 -0
  261. data/test/manual/codemirror_demo.html +773 -0
  262. data/test/manual/create_posts_for_web.rb +114 -0
  263. data/test/manual/environment.rb +67 -0
  264. data/test/manual/make_banner.rb +153 -0
  265. data/test/manual/preview_manual_test.rb +129 -0
  266. data/test/manual/sample_banner_config.txt +12 -0
  267. data/test/manual/test_advanced_widgets.rb +73 -0
  268. data/test/manual/test_banner_combinations.rb +120 -0
  269. data/test/manual/test_banner_features.rb +306 -0
  270. data/test/manual/test_banner_integration.rb +115 -0
  271. data/test/manual/test_banner_radial.rb +87 -0
  272. data/test/manual/test_basic_posts.rb +47 -0
  273. data/test/manual/test_layout_widgets.rb +40 -0
  274. data/test/manual/test_pagination.rb +24 -0
  275. data/test/manual/test_random_posts.rb +38 -0
  276. data/test/manual/test_syntax_highlighting.rb +167 -0
  277. data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
  278. data/test/rubytext/rubytext_demo_test.rb +42 -0
  279. data/test/rubytext/rubytext_testing_guide.md +277 -0
  280. data/test/run_automated_tests.rb +45 -0
  281. data/test/staging/.DS_Store +0 -0
  282. data/test/support/preview_utils.rb +88 -0
  283. data/test/syntax_highlighting_test.lt3 +124 -0
  284. data/test/test_gem_assets.rb +48 -0
  285. data/test/test_helpers.rb +240 -0
  286. data/test/tui_editor_integration_test.rb +296 -0
  287. data/test/tui_integration_test.rb +883 -0
  288. data/test/unit/api.rb +1776 -0
  289. data/test/unit/asset_management.rb +219 -0
  290. data/test/unit/backup_test.rb +451 -0
  291. data/test/unit/clipboard_test.rb +60 -0
  292. data/test/unit/contract_test.rb +69 -0
  293. data/test/unit/core.rb +1211 -0
  294. data/test/unit/deploy_config_test.rb +248 -0
  295. data/test/unit/deploy_test.rb +478 -0
  296. data/test/unit/edit_post_test.rb +168 -0
  297. data/test/unit/gem_asset_management.rb +183 -0
  298. data/test/unit/livetext_basic.rb +57 -0
  299. data/test/unit/livetext_compatibility.rb +82 -0
  300. data/test/unit/parse_cmd_test.rb +260 -0
  301. data/test/unit/permalink_copy_test.rb +211 -0
  302. data/test/unit/post.rb +309 -0
  303. data/test/unit/post_index_config_test.rb +258 -0
  304. data/test/unit/post_state_helpers_test.rb +137 -0
  305. data/test/unit/read_commented_file_test.rb +278 -0
  306. data/test/unit/reddit_test.rb +235 -0
  307. data/test/unit/repo.rb +569 -0
  308. data/test/unit/social_test.rb +366 -0
  309. data/test/unit/syntax_highlighting.rb +70 -0
  310. data/test/unit/theme_management_test.rb +91 -0
  311. data/test/unit/view.rb +498 -0
  312. data/test/unit/widgets.rb +669 -0
  313. data/test/web_integration_test.rb +231 -0
  314. data/test/web_test_helper.rb +218 -0
  315. data/test/web_workflow_test.rb +527 -0
  316. data/test/wizard_test.rb +123 -0
  317. data/ui/README.md +67 -0
  318. data/ui/common/lib/ui_common.rb +8 -0
  319. data/ui/rubytext/README.md +191 -0
  320. data/ui/rubytext/bin/scriptorium-rubytext +402 -0
  321. data/ui/rubytext/lib/rubytext_ui.rb +300 -0
  322. data/ui/tui/bin/scriptorium +1890 -0
  323. data/ui/tui/test/tui_test.rb +23 -0
  324. data/ui/web/app/app.rb +2600 -0
  325. data/ui/web/app/assets/livetext_mode.js +244 -0
  326. data/ui/web/app/error_helpers.rb +150 -0
  327. data/ui/web/app/views/advanced_config.erb +196 -0
  328. data/ui/web/app/views/asset_management.erb +645 -0
  329. data/ui/web/app/views/backup_management.erb +238 -0
  330. data/ui/web/app/views/banner_config.erb +200 -0
  331. data/ui/web/app/views/config_widget.erb +232 -0
  332. data/ui/web/app/views/configure_view.erb +401 -0
  333. data/ui/web/app/views/dashboard.erb +154 -0
  334. data/ui/web/app/views/deploy_config.erb +149 -0
  335. data/ui/web/app/views/edit_pages.erb +363 -0
  336. data/ui/web/app/views/edit_post.erb +175 -0
  337. data/ui/web/app/views/edit_theme.erb +73 -0
  338. data/ui/web/app/views/edit_theme_file.erb +74 -0
  339. data/ui/web/app/views/error_page.erb +29 -0
  340. data/ui/web/app/views/header_config.erb +155 -0
  341. data/ui/web/app/views/layout_config.erb +147 -0
  342. data/ui/web/app/views/navbar_config.erb +411 -0
  343. data/ui/web/app/views/theme_management.erb +130 -0
  344. data/ui/web/app/views/view_dashboard.erb +779 -0
  345. data/ui/web/app/views/widgets.erb +249 -0
  346. data/ui/web/bin/scriptorium-web +164 -0
  347. data/ui/web/test/web_basic_test.rb +38 -0
  348. data/ui/web/test_navbar.txt +7 -0
  349. data/ui/web/tmp/timing.log +17 -0
  350. data/ui/web/tmp/web_server.log +0 -0
  351. metadata +434 -8
  352. data/lib/scriptorium/engine.rb +0 -22
  353. data/test/engine/unit.rb +0 -44
@@ -0,0 +1,142 @@
1
+ .mixin liveblog
2
+
3
+ .post 10
4
+
5
+ .title Immutable data (ditching the wax tablet)
6
+ .pubdate 2015-08-25
7
+ .views computing
8
+ .tags
9
+
10
+ .pin computing
11
+
12
+ .teaser
13
+ A couple of weeks ago, I went to Phoenix training prior to the Lone Star Ruby
14
+ Conference in Austin. I was talking with Bruce Tate, and he shared with me
15
+ some thoughts about functional programming in general.
16
+ .end
17
+
18
+ Obviously Bruce isn't responsible if I misquote him. My memory is faulty.
19
+
20
+ "Functional programming is the future," he told me, "and OOP is dying."
21
+ He pointed to the ever-increasing popularity of multi-core machines and the
22
+ increasing irrelevance of conserving memory.
23
+
24
+ He said that OOP was all about optimizing for memory usage, and that was
25
+ no longer such a big concern. I wasn't sure what he meant. I thought about it
26
+ later, and decided I was probably missing some profound points.
27
+
28
+ But at the same time, I thought I saw something with a clarity that I hadn't
29
+ before. I have wrestled with the concepts of FP over the last year or two; as
30
+ a procedural and OOP type, it hasn't always fit into my brain quickly or
31
+ easily.
32
+
33
+ At times it felt that I was taking a step backwards technologically, back into
34
+ procedural thinking. On the one hand, that isn't really true. On the other
35
+ hand, I think we all know what backtracking is for. If you've ever gotten lost
36
+ in a strange town, you know that sometimes you have to back up to a known
37
+ point and try going off in a different direction.
38
+
39
+ If you're interested, you could make some fine analogies here between human
40
+ technological advances and things like game theory and machine learning. It's
41
+ hard to imagine navigating a maze or implementing a chess-playing program
42
+ without the concept of backtracking. But that's not my point here.
43
+
44
+ One of the key concepts in functional programming, as I understand it, is that
45
+ of immutable data. I have spent hours puzzling over this, because it hasn't
46
+ been immediately intuitive to me.
47
+
48
+ There was a quote I read once that the GOTO statement caused difficulties
49
+ because it left us with the question, "How did I get here?" And mutable data
50
+ leaves us with the question, "How did I get to this state?" That made sense
51
+ to me, at least a little.
52
+
53
+ It got me to thinking about a more remote time, when I taught programming
54
+ concepts to beginners (using BASIC). In an effort to explain how a program
55
+ worked, I would run through an exercise on the whiteboard which I called
56
+ "playing computer." Variables were represented by little boxes which more or
57
+ less corresponded to memory locations. As I manually stepped through the execution
58
+ of some simple program, I would erase and update the contents of these boxes.
59
+
60
+ It was nice and effective, but I sometimes did it another way. I expressed the
61
+ same information in the form of a table, with variable names across the
62
+ columns and time increasing down the rows. This made it clear not just what
63
+ values the variables had, but what values they used to have (and how/when they
64
+ changed).
65
+
66
+ As an aside, I'm one of those people who believes that an education should not
67
+ be merely deep but also broad. I believe a good vocabulary, like a good
68
+ education in general, enhances our experience of life.
69
+
70
+ And as I thought about my old whiteboard shenanigans, the word that came to me
71
+ was _palimpsest -- a beautiful, useful, poetic word that we rarely see nowadays.
72
+ It's sometimes used figuratively; but the literal definition is _(a document on )
73
+ _(which the original writing has been erased and replaced with new writing).
74
+
75
+ I thought about the many older modes of writing, such as clay and wax tablets
76
+ and papyrus. Some materials such as papyrus and parchment (vellum) were rather
77
+ limited in availability or moderately labor-intensive to produce; people wanted
78
+ to re-use them. It was natural to wipe (or scrape or clean) such a material
79
+ once the writing on it was no longer relevant. The term "blank slate" _((tabula rasa))
80
+ was once very literal; the stuff we wrote on was the same as the building material.
81
+
82
+ By the way, what is deemed relevant may change over the course of 1,000 or 2,000
83
+ years. Many an archaeologist or linguist has spent countless frustrating hours
84
+ trying to decipher the original writing under some later inscription. In a
85
+ similar way, art experts have gone to enormous lengths to uncover artworks
86
+ which someone painted over rather than start a new canvas.
87
+
88
+ But what if writing materials were cheap? Today we are much more likely to
89
+ have notepads on our desks than little erasable slates or wax tablets.
90
+
91
+ Let's extend the analogy to computer memory. There was a time, perhaps four
92
+ decades ago, when it was expensive and limited in availabilty. I recall seeing
93
+ an information sheet about a mainframe ("What's a mainframe?" asks everyone
94
+ under 40) that listed its specs, almost bragging about its memory, which was
95
+ 448K. Yes, that is less than half a meg. That computer ran a medium-sized
96
+ university. Within seven years, of course, people were carrying around floppy
97
+ disks that held three times that much. ("What's a floppy disk?" asks everyone
98
+ under 30.)
99
+
100
+ It was only ten years or so prior to that time that the world saw the creation
101
+ of this curious thing called UNIX (a play on the name MULTICS). Some of you
102
+ reading this may have wondered (or not) why UNIX and its offspring stored a
103
+ conceptual newline as a single linefeed character (rather than the somewhat
104
+ more sensible "carriage return + linefeed" combination. The answer is that
105
+ the designers wanted to save RAM and disk space. For every line of text, they
106
+ saved an entire byte in this way. When a linefeed was sent to a device such
107
+ as a terminal or printer, the OS typically converted it to a "real" CRLF pair.
108
+ This all happened because memory was scarce and expensive.
109
+
110
+ It isn't true anymore. In some cases, we may have learned bad habits and
111
+ forgotten how to conserve memory. But in general, we have more imortant things
112
+ to worry about now.
113
+
114
+ But let's think a minute. If memory is cheap and available, why are we
115
+ turning it into a palimpsest? Isn't there something to be said for the idea of
116
+ leaving data alone, never overwriting information, always writing new data
117
+ somewhere else?
118
+
119
+ If we do that, we have a "history" of what has happened in program execution,
120
+ like a trail of breadcrumbs. More importantly, pieces of code that run
121
+ concurrently need not worry about stepping on each other's data. One process
122
+ (or thread or fiber) will never write over an item that another process is
123
+ reading. If this doesn't eliminate synchronization issues, it at least
124
+ mitigates them greatly.
125
+
126
+ So I'm starting to see where immutable data could be a good thing. And I'm
127
+ starting to see how it's good for concurrency. And concurrency really matters,
128
+ because it is the limiting factor of this generation of computing just as
129
+ memory scarcity was a limiting factor one or two generations ago.
130
+
131
+ In fact, I'll speculate a little about memory in general. Let's look 10, 20,
132
+ or even 50 years into the future. (My crystal ball, like everyone else's, is
133
+ very cloudy.)
134
+
135
+ I can imagine a time when memory is simply never erased at all. We're seeing
136
+ the crude beginnings of this already. Source control systems and databases
137
+ preserve far more history than they used to. My laptop's OS encourages me to
138
+ think of my backed-up data as a sort of limitless archive of past versions of
139
+ files. It's mostly an illusion, but it needn't always be. Why should any
140
+ document, any image, any video ever be erased?
141
+
142
+ Food for thought. Chow down, friends.
@@ -0,0 +1,117 @@
1
+ .mixin liveblog
2
+
3
+ .post 11
4
+
5
+ .title Computer science as a lost art
6
+ .pubdate 2015-09-17
7
+ .views computing
8
+ .tags
9
+
10
+ .pin computing
11
+
12
+ .teaser
13
+ An old friend of mine asked me this in email last night...
14
+ .end
15
+
16
+ .quote
17
+ Thanks for taking the time here. My younger son is interested in pursuing
18
+ a career in computer science. He's a freshman at Kennesaw State right now,
19
+ but he really struggles with the idea of taking two years of classes that
20
+ he has very little interest in. There are three schools in Atlanta with
21
+ 8- to 16-week full-day immersive courses that focus solely on technology:
22
+ The Iron Yard, Digital Crafts, and General Assembly.
23
+
24
+ In the world of computer science, what is the opinion is of programs like
25
+ this? Is a 4-year degree viewed as more valuable?
26
+ .end
27
+
28
+ *[This morning, this was my off-the-cuff answer:]
29
+
30
+ Well, here is my opinion... I'm speaking as someone with two degrees and
31
+ therefore six years in comp sci, as well as 30 years' experience. In other words,
32
+ I'm old-fashioned, a freaking dinosaur. :)
33
+
34
+ There is a whole generation of computer people who are very different from the
35
+ previous generation. CS used to be (and really still is) a very deep and demanding
36
+ field.
37
+
38
+ But two or three things have happened. First of all, computers are pretty much
39
+ universal now. Do you know anyone under 80 who doesn't have one? Second, the
40
+ World Wide Web (born in 1989 as a "face" on the more bare-bones Internet)
41
+ started being invaded by the general public in 1995 or so. As usage became more
42
+ common, it became more important to everyday life. And third, the tools we use
43
+ to create applications have gotten a bit more sophisticated. It's easier to use these
44
+ tools, just as it's easier to drive a car now than it was in 1905.
45
+
46
+ What all this means is that there are more kinds of "computer person" than there
47
+ ever were before. There are many thousands of "programmers" who never took
48
+ a programming course. This is both good and bad.
49
+
50
+ It means that a person can get the little things done while knowing very little. But it
51
+ also means that this person probably will never learn enough to get the big things done.
52
+
53
+ To be honest, I get secretly frustrated with the lower-level people who now exist
54
+ in giant hordes. (I rarely tell anyone that.) To me, they are like people who have
55
+ decided to learn 5% of their field in order to get a few things done, have some fun,
56
+ and make a living.
57
+
58
+ These people use tools to create little applications for everyday use. But remember:
59
+ The tools themselves are also software. But they are a level of software far beyond
60
+ anything these people could dream of creating. They use languages, editors,
61
+ compilers, and operating systems; but they don't have the first clue about how to
62
+ create any of these things or even how they really work.
63
+
64
+ In 20 years, some race car driver is going to hold a kid in his lap, and the kid is
65
+ going to say, "Well, I can drive a car, too. Everybody can drive a car. You just
66
+ push the green button and say, 'Take me to Wal-Mart.'" And I kind of feel like that
67
+ race car driver sometimes.
68
+
69
+ Bringing it back to computers... My friend had a 7-year-old who used a fancy tool
70
+ that he learned by himself, and he created a game for the iPhone. Sure, it was a
71
+ simple game. But he did something by himself that a PhD could barely have done
72
+ 30 years ago (and not on a handheld device).
73
+
74
+ To some extent, my complaints are valid. And to some extent, it's just me being
75
+ an old-timer and a curmudgeon.
76
+
77
+ Sometimes I interact with certain people and their complaints and questions show
78
+ where they have reached the boundaries of their knowledge. And sometimes it's
79
+ shocking to me. I think: You should have learned that in your first computer science
80
+ class in your first semester. And then I remember: This person never had a real
81
+ computer science class at all.
82
+
83
+ Of course, generations before me look at me the same way. In the 1940s, you
84
+ pretty much had to have a degree in electrical engineering in order to see or touch
85
+ a computer. In the 70s and early 80s, you just had to be a science or engineering
86
+ major. In the 90s, you just had to have a credit card (or have parents with a credit
87
+ card).
88
+
89
+ I'm very lost with hardware, by the way. I live on the keyboard. Every time I ever
90
+ opened up a computer to try to change something, I screwed up two other things.
91
+ I'm strictly a software guy. I've known people who made fun of me for that, and
92
+ even older people who laughed a little at me because I didn't know how to use a
93
+ soldering iron.
94
+
95
+ It all depends really on what a person really wants to do. If you want to make
96
+ online stores and shopping carts and web forms and pretty pictures and social media
97
+ apps, then you don't need a degree in computer science anymore. Not even an
98
+ associate's degree.
99
+
100
+ If you want to make really interesting exciting things that have never existed before,
101
+ if you want to make a tiny little difference in the industry and change the world just a
102
+ little bit, then you do need that degree. If you want to make the tools and libraries
103
+ that the lower-level people use, you do need that degree.
104
+
105
+ Or look at it this way: If you want to build doghouses, just pick up some skills with
106
+ hammer and nails, and then go for it. If you want to be an architect who designs and
107
+ builds skyscrapers, then go get a degree in architecture first. But please (speaking
108
+ again as a curmudgeon), don't learn to build doghouses and call yourself an architect.
109
+
110
+ I hope this silly rant is helpful in some way. :)
111
+
112
+ Ask me any more detailed questions if you want to.
113
+
114
+ Cheers,
115
+
116
+ Hal
117
+
@@ -0,0 +1,26 @@
1
+ .mixin liveblog
2
+
3
+ .post 12
4
+
5
+ .title Ruby Day in Turin, Italy
6
+ .pubdate 2015-11-10
7
+ .views computing
8
+ .tags
9
+
10
+ .teaser
11
+ I'm honored to be speaking on Friday at Ruby Day in Turin, Italy.
12
+ See http://rubyday.it for the schedule.
13
+ .end
14
+
15
+ I love my career, and I love traveling. It's nice when I get to
16
+ combine them. This is one of those times.
17
+
18
+ I'll be presenting a talk entitled "Elixir for the Rubyist" (the
19
+ same as the title of the book I'm working on).
20
+
21
+ If you're a Periscope user, be aware that I might try to stream
22
+ some of this event (as well as some of my travels around the city).
23
+
24
+ I'll also try to post a link to my slides later (and a video if
25
+ they happen to make one).
26
+
@@ -0,0 +1,28 @@
1
+ .mixin liveblog
2
+
3
+ .post 13
4
+
5
+ .title RubyDay was a success
6
+ .pubdate 2015-11-23
7
+ .views computing
8
+ .tags
9
+
10
+ .teaser
11
+ On November 13, I attended Ruby Day in Turin, Italy. It was well worth the trip.
12
+ .end
13
+
14
+ Like any other Ruby conference, there was an eclectic assemblage of people. I only
15
+ attended the English language talks, as my knowledge of Italian is very minimal.
16
+
17
+ My own talk "Elixir for the Rubyist" was reasonably well attended and well received.
18
+ I'll post a link to the slides and video later.
19
+
20
+ I was personally very impressed by Ju Liu's talk on Sonic Pi. His style of teaching
21
+ was an excellent example of what I call _incremental learning_ (for which there is
22
+ probably a "real" term that I don't know). Additionally, it's hard to imagine anyone
23
+ watching that talk and _not_ wanting to play with Sonic Pi.
24
+
25
+ I also greatly enjoyed the talks by Ramon Huidobro and James Kiesel. Once those videos
26
+ are up, I'll post links to those as well.
27
+
28
+ Turin is a beautiful city. I look forward to going back sometime.
@@ -0,0 +1,42 @@
1
+ .mixin liveblog
2
+
3
+ .post 14
4
+
5
+ .title Working on the blogging software
6
+ .pubdate 2016-04-14
7
+ .views computing
8
+ .tags
9
+
10
+ .teaser
11
+ Everyone warned me not to go down this road. I didn't listen.
12
+ .end
13
+
14
+
15
+ What I've heard is that once you start working on your own
16
+ blogging system, it's a rabbithole. You spend more time working
17
+ on the code than you do blogging.
18
+
19
+ I think I believe it. But is that really so bad? Coding, after all,
20
+ is fun. Isn't that one of the reasons we do it?
21
+
22
+ It's true that I'm spending a lot of time reinventing the wheel (and
23
+ doing it badly). But I'm also implementing features that I've never
24
+ seen anywhere else.
25
+
26
+ And I like those features. They work for me.
27
+
28
+ Besides, working on the Elixir book is plenty of writing. It doesn't
29
+ leave me with much energy for blogging.
30
+
31
+ The big problem, of course, with "eating my own dog food" (as the
32
+ saying goes) is that it only has to be palatable to _(me). It is
33
+ unlikely that my blog code will ever really see the light of day,
34
+ because people would say, "You mean it doesn't even have feature X?"
35
+
36
+ To which I could only reply, "I didn't want feature X."
37
+
38
+ Or, "You mean it doesn't even catch this simple error condition?" To
39
+ which I would have to reply, "I know not to make that error."
40
+
41
+ The first 90% of a software project is fairly easy. It's the second
42
+ 90% where it starts to get painful.
@@ -0,0 +1,137 @@
1
+ .mixin liveblog
2
+
3
+ .post 15
4
+
5
+ .title OK, it's not really a lost art
6
+ .pubdate 2018-07-31
7
+ .views computing
8
+ .tags
9
+
10
+ .pin computing
11
+
12
+ .teaser
13
+ I was surprised to learn that an old blog entry was
14
+ being discussed on reddit. Maybe I should update my comments a little.
15
+ .end
16
+
17
+ It seemed odd to me that a blog I had abandoned (_[mea culpa])
18
+ had generated three emails to me in a single week. Finally
19
+ someone pointed out to me that it had been reposted and was
20
+ getting a little bit of attention.
21
+
22
+ I haven't read all the responses from the numerous redditors.
23
+ Maybe I'll read more later. This is my tentative response.
24
+
25
+ Many have suggested that the speckled background is ugly and
26
+ hard to read. Ugly, probably. Hard to read-- well, it looked
27
+ OK on my screen. But, point taken, it's gone.
28
+
29
+ Someone used the term "elitist sour grapes." That is probably
30
+ largely correct. :)
31
+
32
+ Someone else said you shouldn't trust someone who claims to be
33
+ a web developer but doesn't know CSS. That, I would say, is 100%
34
+ correct.
35
+
36
+ But you see, I do not claim to be a web developer. In fact, I
37
+ specifically claim that I do _not know web development.
38
+
39
+ I realize that web guys have collectively made billions, maybe
40
+ even trillions of dollars over the years. And it is an absolutely
41
+ necessary part of modern society, and I don't want to demean the
42
+ people who are good at it and who want to do it.
43
+
44
+ But web coding as such just doesn't interest me. I'm not good at it,
45
+ and I don't _want to be good at it. I'd rather do other things.
46
+
47
+ I'm not a programming "god" or "rock star," by the way. I'm
48
+ just a guy who's been doing this a long time, but has not stuck
49
+ to one thing long enough to be considered brilliant.
50
+
51
+ The user LondonPilot raises some very interesting points. I wish I
52
+ could buy him a beer or six (or substitute beverage of choice).
53
+
54
+ In fact, his argument is sort of the flip side of mine-- and arguably
55
+ the more important angle on the whole situation. I would even say that
56
+ I have made the same argument at different times and places in the past.
57
+
58
+ Here's a good example. I recall a time in the early 90s, when personal
59
+ computers were less common, I had two friends who had recently got
60
+ married. He was an electrical engineer, and she majored (I think) in
61
+ English. This was 1992, when Windows 3.1 was hip and trendy in some
62
+ circles, and DOS was still very much alive.
63
+
64
+ Jon slightly bemoaned the fact that Joyce used a Mac rather than a PC.
65
+ He made the comment that "people don't learn anything about computers
66
+ that way." I suspect from his hardware-oriented point of view, the DOS
67
+ command line was pretty super-high-level.
68
+
69
+ In some ways, I sympathized. But I made the counter-argument that a
70
+ toaster is meant to toast bread, not to teach us about electricity.
71
+ (He hated this analogy.) But I often felt the computer should become
72
+ invisible-- that the proper response to "What are you doing?" should
73
+ be "I'm writing a paper" or "I'm designing a graphic" or whatever--
74
+ it should never be "I'm using the computer." And we've made some great
75
+ progress there in recent decades.
76
+
77
+ Let me amend what I said before. I don't _mean to backtrack (though I
78
+ probably will), but to clarify and expand.
79
+
80
+ First of all, there _are in fact certain small lessons from computer
81
+ science that even a modern "clean hands" developer should know. I
82
+ cannot _count the number of times I have seen a programmer (and I
83
+ really wanted to put quotes around that) who was absolutely _incensed
84
+ that `[(2.0/3.0)*3.0] was only `1.99999999 or thereabouts. I have seen
85
+ people who were _livid and demanded that this bug be fixed.
86
+
87
+ I have also had difficulty explaining that no matter how fast your
88
+ processor is, an algorithm that is `[O(N^2)] can eventually bite you.
89
+ I have seen people who didn't know that hard disk access is typically
90
+ slower than memory access. I could go on.
91
+
92
+ Having said that: You can get an awful lot done these days without any
93
+ CS coursework. You can create things that are useful, worthwhile, and
94
+ certainly financially successful.
95
+
96
+ And there is nothing magical about a degree anyway. What counts is
97
+ domain knowledge-- and I mean enough knowledge to be truly effective,
98
+ not just "enough to fool your manager" (and perhaps not just "enough
99
+ to pass a boot camp").
100
+
101
+ So getting back to the excellent comments by LondonPilot-- I think
102
+ perhaps there should be another field or discipline split off from
103
+ computer science. This would be parallel to what I believe happened
104
+ with electrical engineering and computer science.
105
+
106
+ I studied CS for 6 years, and as far as I recall, I only had two or
107
+ three EE courses (including one lab). To the generation before mine,
108
+ that might seem like a horrifying concept.
109
+
110
+ So let's imagine a new major. I don't know what to call it-- maybe
111
+ "High-Level Computing"? Not a great neologism, but I'll run with it
112
+ for now. An HLC major would certainly have one or two courses that
113
+ were from traditional CS (just as I myself had my fleeting glimpse
114
+ at EE material). But the rest would be more pragmatic, more about
115
+ gluing this piece of tech to that one, properly trusting that the
116
+ components were created and tested by CS people-- just as I properly
117
+ trust that my CPU works as advertised and never try to build my own.
118
+
119
+ As LondonPilot said, this is not a bad thing. This is how human
120
+ progress works.
121
+
122
+ I do wish that more web developers had deeper knowledge. But (and
123
+ here I may truly be backtracking)-- it does not have to be super-
124
+ deep knowledge. I probably said it did, but I was wrong, of course.
125
+ As long as there are cars, there will be people who understand the
126
+ workings of the engines; but a self-driving car will be perfectly
127
+ useful in getting from point A to point B. Part of the point of
128
+ technology is to make it easier to accomplish tasks with less effort
129
+ and less specialized knowledge.
130
+
131
+ So my modest proposal would be: Let CS give birth to a new field
132
+ just as EE gave birth to CS. EE did not die, and CS will not die
133
+ in the imaginable future. Let's just admit these are different
134
+ ways of thinking now, and should perhaps be different tracks.
135
+
136
+ Thank you to all who responded. Maybe I'll dust off this blog again
137
+ soon.
@@ -0,0 +1,142 @@
1
+ .mixin liveblog
2
+ . ^ get rid of this later
3
+
4
+ .post 16
5
+
6
+ .title An 'in' operator for Ruby
7
+ .pubdate 2019-11-13
8
+ .views computing
9
+ .tags
10
+
11
+ .pin computing
12
+
13
+ .teaser
14
+ I have had two fairly small changes I wanted to make in Ruby. The first
15
+ was realized years ago.
16
+ .end
17
+
18
+ Hashes now preserve insertion order and iterate in a predictable way.
19
+ That's fairly minor, but it did/does have some use cases, and it had no impact
20
+ on performance.
21
+
22
+ Here's another one. Personally, this is a bigger thing to me.
23
+
24
+ <b>I've always believed personally that Ruby should have an `in operator.</b>
25
+
26
+ I've mentioned this in speaking (including lightning talks) and in writing.
27
+ It's not a _giant big deal for me, but it is one of my personal favorite ideas.
28
+ Here are some details.
29
+
30
+ *[My proposal]
31
+
32
+ I propose to let `[ x in y] be syntax sugar for `[y.include? x]
33
+
34
+ *[You may ask: Why?]
35
+
36
+ <ul>
37
+ <li> `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.</li>
38
+
39
+ <li>Ruby isn't English; and more generally, programming languages aren't human languages. But programming languages are <i>based<i></i></i> 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 <i>about the group</i>. <br><br> `[if barrel.include? rotten\_apple # Is barrel going bad?] <br><br></li>
40
+
41
+ <li>But we also -- perhaps more often? -- ask questions like "Is this item part of this group?" We are asking a question <i>about the item</i>. <br><br> `[if fruit in [:apple, :pear, :peach\] # Is this fruit something I like?] <br><br>
42
+
43
+ <li> `[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.
44
+
45
+ <li>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.
46
+
47
+ .code
48
+ if foo == var1 ||
49
+ foo =~ var2 ||
50
+ foo < var3 ||
51
+ var4.include?(foo) || # <== This is the ugly part
52
+ foo > var5]
53
+ .end
54
+
55
+ To quote him as well as I remember: "I was having this perfectly nice conversation
56
+ with ``foo, and then `var4 interrupted it..."
57
+
58
+ Better:
59
+
60
+ .code
61
+ if foo == var1 ||
62
+ foo =~ var2 ||
63
+ foo < var3 ||
64
+ foo in var4 ||
65
+ foo > var5]
66
+ .end
67
+
68
+ <li>I prefer to put the tested entity earlier in the statement:</li>
69
+ .code
70
+ if [GA, VA, MS, TX, MD, NC].include? state # ehhhh
71
+ if state in [GA, VA, MS, TX, MD, NC] # better</tt>
72
+ .end
73
+
74
+ <li>Also a "variable/constant" issue -- I tend to put the variable data on the
75
+ left and the constant on right; this is unlike people who say `[if 5 == x].
76
+ (After all, `5 is only equal to `x very rarely; `5 is <i>always</i> equal to 5,
77
+ even for very large values of 5.)
78
+
79
+ <li>Also a question of focus: Whatever entity you are really dealing with,
80
+ name that one first.
81
+
82
+ <li>Many languages already have an `in operator -- notably Python, Pascal,
83
+ even SQL. It is familiar to users of those languages as well as those
84
+ who use mathematical notation.
85
+
86
+ <li> `in is already a reserved word in Ruby -- used in the `for loop (syntax
87
+ sugar for `[each]). Let's increase the justification for its presence.
88
+
89
+ <li>An `in operator would sometimes make parentheses unnecessary:</li>
90
+ .code
91
+ if (10..100).include? x # Need parens
92
+ if x in 10..100 # Don't need parens -- also prettier code
93
+ .end
94
+
95
+ <li>The newer language Elixir (which I'm happy to report occupies a lot of my
96
+ time lately) also sports this operator. This is yet another reason to
97
+ love that language.
98
+ </ul>
99
+
100
+ <b>Frequently Whined Whines</b>
101
+ <p>
102
+ <ul>
103
+ <li><b>I'd prefer a method.</b> I understand this, but I find it to be
104
+ needlessly ugly. I like less punctuation, more whitespace. And I
105
+ find this inappropriate for something that is conceptually an operator.
106
+
107
+ .code
108
+ if x.in mylist # ugly
109
+ if x.== 5 # also ugly
110
+ if c1.and c2 # ugly - if it worked
111
+ if x == 5 # better
112
+ if c1 and c2 # better
113
+ if x in mylist # better
114
+ .end
115
+
116
+ <li><b>I'd prefer a method with a</b> <tt>?</tt> <b>on it.</b> I understand
117
+ the concept, too, but I find it inappropriate for what is inherently a relational operator.
118
+
119
+ .code
120
+ if x.in? my\_set # very ugly
121
+ if x.==? 5 # very ugly - if it worked
122
+
123
+ if x in my\_set # natural
124
+ if x == 5 # natural
125
+ .end
126
+
127
+ <li><b>What about</b> `[for x in list] <b>? Would this evaluate as </b>
128
+ `[for true] <b> or </b> `[for false] <b>?</b> Certainly not. It's a matter
129
+ of parsing. The `for loop itself is just syntax sugar.
130
+
131
+ <li><b>I'll bet you like junctions, too.</b> No, in fact, I dislike junctions greatly. I don't even know Perl. Are junctions still a thing?
132
+
133
+ <li><b>If you like SQL's</b> <tt>in</tt> <b>, you must like</b> <tt>not in</tt> <b><b>also.</b></b> No, I don't condone its use of "not in":
134
+
135
+ <tt>if item not in collection # travesty!</tt> <tt>if ! (item in collection) # ok</tt>
136
+
137
+ <tt>if x not == y # horrible Ruby travesty - if it worked</tt> Yes, I say this even though <tt>! ( item in collection)</tt> requires parentheses. See the comment about parentheses on ranges.
138
+
139
+ <li><b>What about precedence?</b> I would place <tt>in</tt> at the same level of precedence as the (other) relational operators <tt>< > <= >=</tt> etc.</ul><b>Conclusion</b>
140
+ <p>
141
+ People have ignored me on this for at least ten years. They probably still will.
142
+ That, as they say, is life.