galaaz 0.5.0 → 2.0.0

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 (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/LICENSE +0 -0
  4. data/README.md +1360 -636
  5. data/Rakefile +61 -41
  6. data/bin/galaaz-bootstrap +137 -0
  7. data/bin/galaaz-jruby +14 -0
  8. data/bin/galaaz_jruby_env.inc.sh +6 -0
  9. data/bin/gbookdown +64 -0
  10. data/bin/gknit +84 -13
  11. data/bin/gknit-draft.rb +0 -0
  12. data/bin/gstudio +5 -3
  13. data/bin/gstudio_irb.rb +0 -0
  14. data/bin/gstudio_pry.rb +0 -0
  15. data/bin/install-tinytex +6 -0
  16. data/bin/run_all_rspec +43 -0
  17. data/bin/run_example +14 -0
  18. data/bin/run_old_rspec +19 -0
  19. data/bin/run_rspec +23 -0
  20. data/bin/run_rspec_subset +38 -0
  21. data/bin/run_slow_rspec +19 -0
  22. data/blogs/R-on-Rails-Planning-Document.md +940 -0
  23. data/blogs/README.md +100 -0
  24. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
  25. data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
  26. data/blogs/galaaz_ggplot/galaaz_ggplot.md +115 -155
  27. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
  28. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
  29. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
  30. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
  31. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
  32. data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
  33. data/blogs/galaaz_ggplot/midwest_external_png +0 -0
  34. data/blogs/gknit/gknit.Rmd +47 -52
  35. data/blogs/gknit/gknit.md +1430 -0
  36. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  37. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  38. data/blogs/gknit/lst.rds +0 -0
  39. data/blogs/gknit/model.rb +1 -1
  40. data/blogs/gknit/stats.bib +0 -0
  41. data/blogs/manual/include_model_local_repro.Rmd +14 -0
  42. data/blogs/manual/include_model_local_repro.md +75 -0
  43. data/blogs/manual/lst.rds +0 -0
  44. data/blogs/manual/manual.Rmd +852 -239
  45. data/blogs/manual/manual.log +1786 -0
  46. data/blogs/manual/manual.md +1360 -636
  47. data/blogs/manual/manual.tex +1883 -1161
  48. data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
  49. data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
  50. data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
  51. data/blogs/manual/model.rb +1 -1
  52. data/blogs/nse_dplyr/nse_dplyr.Rmd +84 -111
  53. data/blogs/nse_dplyr/nse_dplyr.log +928 -0
  54. data/blogs/nse_dplyr/nse_dplyr.md +198 -229
  55. data/blogs/oh_my/not_so.rb +0 -0
  56. data/blogs/oh_my/oh_my.Rmd +1234 -25
  57. data/blogs/oh_my/oh_my.log +804 -0
  58. data/blogs/oh_my/oh_my.md +1663 -86
  59. data/blogs/oh_my/oh_my.tex +821 -0
  60. data/blogs/oh_my/old.Rmd +15 -14
  61. data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
  62. data/blogs/ruby_plot/ruby_plot.log +885 -0
  63. data/blogs/ruby_plot/ruby_plot.md +71 -102
  64. data/blogs/ruby_plot/ruby_plot.tex +940 -0
  65. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
  66. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
  67. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
  68. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
  69. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
  70. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  71. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
  72. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
  73. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
  74. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
  75. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
  76. data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
  77. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
  78. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
  79. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
  80. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
  81. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
  82. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
  83. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
  84. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
  85. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
  86. data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
  87. data/blogs/test/test.Rmd +14 -0
  88. data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
  89. data/examples/50Plots_MasterList/ScatterPlot.rb +0 -0
  90. data/examples/50Plots_MasterList/scatter_plot.rb +0 -0
  91. data/examples/Bibliography/master.bib +0 -0
  92. data/examples/Bibliography/stats.bib +0 -0
  93. data/examples/R/calc.R +0 -0
  94. data/examples/R/java_interop.R +0 -0
  95. data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
  96. data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +53 -0
  97. data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
  98. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +33 -0
  99. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +34 -0
  100. data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
  101. data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
  102. data/examples/islr/all.rb +13 -0
  103. data/examples/islr/ch2.spec.rb +37 -7
  104. data/examples/islr/ch3.spec.rb +11 -2
  105. data/examples/islr/ch3_boston.rb +27 -0
  106. data/examples/islr/ch3_multiple_regression.rb +0 -0
  107. data/examples/islr/ch6.spec.rb +24 -1
  108. data/examples/islr/x_y_rnorm.jpg +0 -0
  109. data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +0 -0
  110. data/examples/latex_templates/Test-acm_article/sigproc.bib +0 -0
  111. data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +0 -0
  112. data/examples/latex_templates/Test-acs_article/acs-my_output.bib +0 -0
  113. data/examples/latex_templates/Test-aea_article/BibFile.bib +0 -0
  114. data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +0 -0
  115. data/examples/latex_templates/Test-aea_article/references.bib +0 -0
  116. data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +0 -0
  117. data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +0 -0
  118. data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +0 -0
  119. data/examples/latex_templates/Test-ieee_article/mybibfile.bib +0 -0
  120. data/examples/latex_templates/Test-rjournal_article/RJournal.sty +0 -0
  121. data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +0 -0
  122. data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +0 -0
  123. data/examples/misc/baseball.csv +0 -0
  124. data/examples/misc/ggplot.rb +3 -2
  125. data/examples/misc/moneyball.rb +0 -0
  126. data/examples/misc/subsetting.rb +0 -0
  127. data/examples/multithread_shards_to_r/shards_to_r.rb +67 -0
  128. data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +0 -0
  129. data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +0 -0
  130. data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +0 -0
  131. data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +0 -0
  132. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +0 -0
  133. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +0 -0
  134. data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +0 -0
  135. data/examples/sthda_ggplot/README.md +0 -0
  136. data/examples/sthda_ggplot/RUN.md +41 -0
  137. data/examples/sthda_ggplot/all.rb +0 -0
  138. data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +0 -0
  139. data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +0 -0
  140. data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +2 -0
  141. data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +0 -0
  142. data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +0 -0
  143. data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +0 -0
  144. data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +0 -0
  145. data/examples/sthda_ggplot/one_variable_continuous/stat.rb +0 -0
  146. data/examples/sthda_ggplot/one_variable_discrete/bar.rb +0 -0
  147. data/examples/sthda_ggplot/qplots/box_violin_dot.rb +0 -0
  148. data/examples/sthda_ggplot/qplots/scatter_plots.rb +0 -0
  149. data/examples/sthda_ggplot/scatter_gg.rb +0 -0
  150. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +0 -0
  151. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +0 -0
  152. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +0 -0
  153. data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +0 -0
  154. data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +0 -0
  155. data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +0 -0
  156. data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +4 -3
  157. data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +0 -0
  158. data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +0 -0
  159. data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +0 -0
  160. data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +0 -0
  161. data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +0 -0
  162. data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +0 -0
  163. data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +0 -0
  164. data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +0 -0
  165. data/ext/new_bridge/Makefile +46 -0
  166. data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
  167. data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
  168. data/lib/R_interface/galaaz_device.R +20 -0
  169. data/lib/R_interface/include_engine.R +109 -0
  170. data/lib/R_interface/new_bridge_adapter.rb +824 -0
  171. data/lib/R_interface/r.rb +177 -25
  172. data/lib/R_interface/r_arrow.rb +113 -0
  173. data/lib/R_interface/r_libs.R +3 -3
  174. data/lib/R_interface/r_methods.rb +13 -126
  175. data/lib/R_interface/r_module_s.rb +0 -0
  176. data/lib/R_interface/rbinary_operators.rb +20 -2
  177. data/lib/R_interface/rclosure.rb +5 -1
  178. data/lib/R_interface/rdata_frame.rb +34 -70
  179. data/lib/R_interface/rdevice.rb +125 -0
  180. data/lib/R_interface/rdevices.R +0 -0
  181. data/lib/R_interface/renvironment.rb +10 -4
  182. data/lib/R_interface/rexpression.rb +5 -1
  183. data/lib/R_interface/rindexed_object.rb +41 -13
  184. data/lib/R_interface/rlanguage.rb +20 -62
  185. data/lib/R_interface/rlist.rb +115 -25
  186. data/lib/R_interface/rlogical_operators.rb +0 -0
  187. data/lib/R_interface/rmatrix.rb +2 -11
  188. data/lib/R_interface/rmd_indexed_object.rb +5 -1
  189. data/lib/R_interface/robject.rb +348 -290
  190. data/lib/R_interface/rpkg.rb +0 -0
  191. data/lib/R_interface/rsupport.rb +609 -328
  192. data/lib/R_interface/rsupport_scope.rb +2 -1
  193. data/lib/R_interface/rsymbol.rb +50 -0
  194. data/lib/R_interface/ruby_callback.rb +2 -3
  195. data/lib/R_interface/ruby_extensions.rb +225 -175
  196. data/lib/R_interface/runary_operators.rb +0 -0
  197. data/lib/R_interface/rvector.rb +147 -31
  198. data/lib/galaaz.rb +0 -0
  199. data/lib/galaaz_jruby.rb +22 -0
  200. data/lib/gknit/diagnostics.rb +50 -0
  201. data/lib/gknit/draft.rb +23 -17
  202. data/lib/gknit/include_engine.rb +15 -7
  203. data/lib/gknit/knitr_engine.rb +223 -74
  204. data/lib/gknit/rb_engine.rb +3 -3
  205. data/lib/gknit/ruby_engine.rb +0 -0
  206. data/lib/gknit.rb +1 -0
  207. data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
  208. data/lib/new_bridge/envelope.rb +51 -0
  209. data/lib/new_bridge/eval_result.rb +26 -0
  210. data/lib/new_bridge/framing.rb +39 -0
  211. data/lib/new_bridge/instance_pool_client.rb +38 -0
  212. data/lib/new_bridge/r_instance_manager.rb +404 -0
  213. data/lib/new_bridge/session_client.rb +530 -0
  214. data/lib/new_bridge/tcp_framed.rb +44 -0
  215. data/lib/new_bridge.rb +9 -0
  216. data/lib/util/exec_ruby.rb +95 -20
  217. data/lib/util/inline_file.rb +35 -30
  218. data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
  219. data/new_bridge_specs/eval_r_async_spec.rb +113 -0
  220. data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
  221. data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
  222. data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
  223. data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
  224. data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
  225. data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
  226. data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
  227. data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
  228. data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
  229. data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
  230. data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
  231. data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
  232. data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
  233. data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
  234. data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
  235. data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
  236. data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
  237. data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
  238. data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
  239. data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
  240. data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
  241. data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
  242. data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
  243. data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
  244. data/r_requires/ggplot.rb +0 -0
  245. data/r_requires/knitr.rb +0 -0
  246. data/specs/all.rb +15 -11
  247. data/specs/arrow_from_ruby_batches_spec.rb +50 -0
  248. data/specs/arrow_semantics_spec.rb +64 -0
  249. data/specs/bridge_concurrent_spec.rb +46 -0
  250. data/specs/bridge_nested_spec.rb +25 -0
  251. data/specs/dataframe_semantics_spec.rb +122 -0
  252. data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
  253. data/specs/dispatch_probe_cache_spec.rb +38 -0
  254. data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
  255. data/specs/dispatch_probe_fallback_spec.rb +18 -0
  256. data/specs/environment_semantics_spec.rb +89 -0
  257. data/specs/field_access_spec.rb +31 -0
  258. data/specs/figures/bg.jpeg +0 -0
  259. data/specs/figures/bg.png +0 -0
  260. data/specs/figures/bg.svg +168 -57
  261. data/specs/figures/dose_len.png +0 -0
  262. data/specs/figures/no_args.jpeg +0 -0
  263. data/specs/figures/no_args.png +0 -0
  264. data/specs/figures/no_args.svg +168 -57
  265. data/specs/figures/width_height.jpeg +0 -0
  266. data/specs/figures/width_height.png +0 -0
  267. data/specs/figures/width_height_units1.jpeg +0 -0
  268. data/specs/figures/width_height_units1.png +0 -0
  269. data/specs/figures/width_height_units2.jpeg +0 -0
  270. data/specs/figures/width_height_units2.png +0 -0
  271. data/specs/formula_semantics_spec.rb +81 -0
  272. data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
  273. data/specs/galaaz_util_inline_file_spec.rb +54 -0
  274. data/specs/gknit_cli_option_permutation_spec.rb +24 -0
  275. data/specs/gknit_include_engine_spec.rb +72 -0
  276. data/specs/gknit_install_timeout_report_spec.rb +69 -0
  277. data/specs/gknit_internal_error_report_spec.rb +57 -0
  278. data/specs/gknit_vector_map_output_spec.rb +59 -0
  279. data/specs/globalenv_guardrail_spec.rb +52 -0
  280. data/specs/language_expression_semantics_spec.rb +145 -0
  281. data/specs/list_semantics_spec.rb +111 -0
  282. data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
  283. data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
  284. data/specs/new_bridge_callback_timeout_spec.rb +69 -0
  285. data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
  286. data/specs/nil_null_spec.rb +42 -0
  287. data/specs/object_build_phase2_spec.rb +53 -0
  288. data/specs/phase1_callback_bridge_spec.rb +84 -0
  289. data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
  290. data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
  291. data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
  292. data/specs/plot_device_semantics_spec.rb +28 -0
  293. data/specs/plot_snapshot_semantics_spec.rb +58 -0
  294. data/specs/protocol_result_spec.rb +236 -0
  295. data/specs/r_batch_fail_fast_spec.rb +47 -0
  296. data/specs/r_bridge_bootstrap_spec.rb +11 -0
  297. data/specs/r_devices.spec.rb +1 -1
  298. data/specs/r_eval.spec.rb +16 -18
  299. data/specs/r_function.spec.rb +1 -1
  300. data/specs/r_instance_manager_spec.rb +285 -0
  301. data/specs/r_list_apply.spec.rb +15 -15
  302. data/specs/r_matrix.spec.rb +0 -0
  303. data/specs/r_nse.spec.rb +5 -5
  304. data/specs/r_object_send_dispatch_spec.rb +13 -0
  305. data/specs/r_vector_comparator_spec.rb +8 -0
  306. data/specs/r_vector_creation.spec.rb +0 -0
  307. data/specs/r_vector_functions.spec.rb +0 -0
  308. data/specs/r_vector_object.spec.rb +0 -0
  309. data/specs/r_vector_operators.spec.rb +0 -0
  310. data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
  311. data/specs/r_vector_subsetting.spec.rb +0 -0
  312. data/specs/range_helper_spec.rb +21 -0
  313. data/specs/rsupport_scope_spec.rb +28 -0
  314. data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
  315. data/specs/scalar_character_spec.rb +44 -0
  316. data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
  317. data/specs/session_env_bridge_spec.rb +25 -0
  318. data/specs/simplecov_bootstrap_spec.rb +10 -0
  319. data/specs/spec_helper.rb +10 -0
  320. data/specs/tmp.rb +0 -0
  321. data/specs/unboxing_recursion_regression_spec.rb +30 -0
  322. data/specs/unboxing_spec.rb +49 -0
  323. data/specs/verify_callbacks.rb +42 -0
  324. data/sty/galaaz.sty +0 -0
  325. data/version.rb +1 -1
  326. metadata +194 -64
  327. data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -520
  328. data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
  329. data/blogs/galaaz_ggplot/midwest.html +0 -188
  330. data/blogs/gknit/gknit.html +0 -2266
  331. data/blogs/gknit/gknit.pdf +0 -0
  332. data/blogs/manual/manual.html +0 -4638
  333. data/blogs/manual/manual.pdf +0 -0
  334. data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
  335. data/blogs/nse_dplyr/nse_dplyr.html +0 -878
  336. data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
  337. data/blogs/oh_my/oh_my.html +0 -568
  338. data/blogs/ruby_plot/ruby_plot.html +0 -544
  339. data/blogs/ruby_plot/ruby_plot.pdf +0 -0
  340. data/examples/latex_templates/Test-acs_article/Test-acs_article.pdf +0 -0
  341. data/examples/latex_templates/Test-aea_article/Test-aea_article.pdf +0 -0
  342. data/examples/latex_templates/Test-amq_article/Test-amq_article.pdf +0 -0
  343. data/examples/latex_templates/Test-amq_article/pics/Figure2.pdf +0 -0
  344. data/examples/latex_templates/Test-asa_article/Test-asa_article.pdf +0 -0
  345. data/examples/latex_templates/Test-ieee_article/Test-ieee_article.pdf +0 -0
  346. data/examples/latex_templates/Test-rjournal_article/RJwrapper.pdf +0 -0
  347. data/examples/latex_templates/Test-springer_article/Test-springer_article.pdf +0 -0
  348. data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.pdf +0 -0
  349. data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.pdf +0 -0
  350. data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.pdf +0 -0
  351. data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.pdf +0 -0
  352. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.pdf +0 -0
  353. data/specs/r_dataframe.spec.rb +0 -379
  354. data/specs/r_environment.spec.rb +0 -140
  355. data/specs/r_formula.spec.rb +0 -232
  356. data/specs/r_language.spec.rb +0 -112
  357. data/specs/r_list.spec.rb +0 -293
  358. data/specs/r_plots.spec.rb +0 -72
  359. data/specs/ruby_expression.spec.rb +0 -316
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe 'Language and expression semantics' do
6
+ context 'symbol conversion and expression building' do
7
+ before(:each) do
8
+ R.len = 10
9
+ R.sd = 20
10
+ R.x = 5
11
+ end
12
+
13
+ it "converts Ruby Symbol to R symbol with unary '+'" do
14
+ sym = +R[:len]
15
+ expect(sym).to be_a(R::RSymbol)
16
+ expect(sym.to_s).to eq('len')
17
+ expect(sym.eval).to eq 10
18
+ end
19
+
20
+ it 'builds language expressions from symbol arithmetic' do
21
+ expr = R[:len] + R[:sd] + 5
22
+ expect(expr).to be_a(R::Language)
23
+ expect(expr.to_s).to eq('len + sd + 5L')
24
+ expect(expr.eval).to eq R.c(35)
25
+ end
26
+
27
+ it 'supports comparison operators in expressions' do
28
+ df = R.data__frame(a: (1..5), b: (5..1))
29
+ e = R[:a] > R[:b]
30
+ expect(e.to_s).to eq('a > b')
31
+ expect(e.eval(df)).to eq R.c(false, false, false, true, true)
32
+ end
33
+
34
+ it 'supports custom infix operators with scoped symbols' do
35
+ e = R[:month]._ :in, R.c(11, 12)
36
+ expect(e.to_s).to include('month %in%')
37
+ df = R.data__frame(month: R.c(10, 11, 12, 1))
38
+ expect(e.eval(df)).to eq R.c(false, true, true, false)
39
+ end
40
+
41
+ it 'supports quoted function construction through E helper' do
42
+ exp = E.sin(:len)
43
+ expect(exp).to be_a(R::Language)
44
+ expect(exp.to_s).to eq('sin(len)')
45
+ expect(exp.eval).to eq R.c(Math.sin(10))
46
+ end
47
+ end
48
+
49
+ context 'evaluation with context objects' do
50
+ it 'evaluates composite arithmetic expression in list context' do
51
+ ctx = R.list(a: 10, b: 20, c: 30)
52
+ val = R.eval(R[:a] + R[:b] * R[:c], ctx)
53
+ expect(val).to eq 610
54
+ end
55
+
56
+ it 'evaluates expression against global binding when no context is provided' do
57
+ R.x = 5
58
+ expect(R.eval(R[:x] + 10)).to eq 15
59
+ end
60
+
61
+ it 'evaluates expression in list context via R.eval(expr, ctx)' do
62
+ ctx = R.list(x: 20)
63
+ val = R.eval(R[:x] + 10, ctx)
64
+ expect(val).to be_a(R::Vector)
65
+ expect(val >> 0).to eq 30
66
+ end
67
+
68
+ it 'uses expression predicates in subset()' do
69
+ df = R.data__frame(a: (1..5), b: (5..1), c: R.c(5, 3, 1, 4, 1))
70
+ sub = R.subset(df, R[:a] >= 4)
71
+ expect(sub).to be_a(R::DataFrame)
72
+ expect(sub.nrow >> 0).to eq 2
73
+ expect(sub[1, 1]).to eq 4
74
+ expect(sub[2, 2]).to eq 1
75
+ end
76
+
77
+ it 'supports scoped arithmetic expressions inside mutate assignments' do
78
+ ok = R::Support.eval("requireNamespace('dplyr', quietly=TRUE)")
79
+ skip 'dplyr is not available' unless ok == true
80
+ R.library('dplyr')
81
+
82
+ flights_sm = R.data__frame(
83
+ dep_delay: R.c(10, 20),
84
+ arr_delay: R.c(5, 7),
85
+ distance: R.c(300, 600),
86
+ air_time: R.c(60, 120)
87
+ ).mutate(
88
+ gain: R[:dep_delay] - R[:arr_delay],
89
+ speed: R[:distance] / R[:air_time] * 60
90
+ )
91
+
92
+ expect(flights_sm[['gain']][1]).to eq 5
93
+ expect(flights_sm[['gain']][2]).to eq 13
94
+ expect(flights_sm[['speed']][1]).to eq 300
95
+ expect(flights_sm[['speed']][2]).to eq 300
96
+ end
97
+
98
+ it 'supports scoped chained list call for column selection expressions' do
99
+ expr = R[:arr_delay].list
100
+ expect(expr).to be_a(R::Language)
101
+ expect(expr.to_s).to eq('list(arr_delay)')
102
+ end
103
+ end
104
+
105
+ context 'reintroduced rlang helper APIs' do
106
+ before(:all) do
107
+ ok = R::Support.eval("requireNamespace('rlang', quietly=TRUE)")
108
+ skip 'R package rlang is not available' unless ok == true
109
+ end
110
+
111
+ it 'supports R.expr for symbol construction' do
112
+ R.len = 10
113
+ exp = R.expr(:len)
114
+ expect(exp).to be_a(R::RSymbol)
115
+ expect(exp.eval).to eq 10
116
+ end
117
+
118
+ it 'supports R.expr for boolean literals' do
119
+ expect(R.expr(true)).to eq R.c(true)
120
+ expect(R.expr(false)).to eq R.c(false)
121
+ end
122
+
123
+ it 'supports R.call2 for call construction' do
124
+ e = R.call2('mean', x: +R[:x], na__rm: true)
125
+ expect(e).to be_a(R::Language)
126
+ expect(e.to_s).to eq('mean(x = x, na.rm = TRUE)')
127
+ end
128
+
129
+ it 'supports R.call2 for assignment calls' do
130
+ e = R.call2('<-', R.expr(:x), 10)
131
+ e.eval
132
+ expect(~R[:x]).to eq 10
133
+ end
134
+
135
+ it 'supports R.exec for dynamic function execution' do
136
+ val = R.exec('mean', x: (1..10), na__rm: true, trim: 0.1)
137
+ expect(val).to eq 5.5
138
+ end
139
+
140
+ it 'supports R.exec with splatted argument hashes' do
141
+ args = [x: (1..10), na__rm: true, trim: 0.1]
142
+ expect(R.exec('mean', *args)).to eq 5.5
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe R::List do
6
+ context 'creation and unboxing' do
7
+ it 'creates empty and populated lists' do
8
+ empty = R.list
9
+ expect(empty.length).to eq 0
10
+ expect(empty).to be_a(R::List)
11
+
12
+ l = R.list(1, a: 2, b: 3, c: R.list(4, 5, 6))
13
+ expect(l.length).to eq 4
14
+ expect(l >> 0).to eq 1
15
+ expect(l >> 3).to eq [4, 5, 6]
16
+ expect(l['k'] >> 0).to eq nil
17
+ end
18
+ end
19
+
20
+ context "subsetting with '[' and '[['" do
21
+ before(:each) do
22
+ @l = R.list(a: 1, b: 2, all: 3, d: R.list(i: 4, j: 5, all: 6))
23
+ end
24
+
25
+ it 'returns a list when using []' do
26
+ expect(@l[1]).to eq R.list(a: 1)
27
+ expect(@l[-4] == R.list(a: 1, b: 2, all: 3)).to eq true
28
+ expect(@l[R.c(4, 1)] == R.list(d: R.list(i: 4, j: 5, all: 6), a: 1)).to eq true
29
+ end
30
+
31
+ it 'raises bridge process error when [] receives wrong index dimension' do
32
+ expect { @l[4, 1] }.to raise_error(NewBridge::SessionClient::RProcessError)
33
+ end
34
+
35
+ it 'returns elements when using [[]]' do
36
+ raw = R.list(1, 2, 3, R.list(4, 5, 6))
37
+ expect(raw[[1]]).to eq 1
38
+ expect(raw[[4]].identical(R.list(4, 5, 6))).to eq true
39
+ expect(raw[[4]][[1]]).to eq 4
40
+ expect(raw[[R.c(4, 1)]]).to eq 4
41
+ end
42
+ end
43
+
44
+ context 'named access and assignment' do
45
+ before(:each) do
46
+ @l = R.list(a: 1, b: 2, c: 3, d: R.list(i: 4, j: 5, k: 6))
47
+ end
48
+
49
+ it 'supports dot access for named elements' do
50
+ expect(@l.a).to eq 1
51
+ expect(@l.d.identical(R.list(i: 4, j: 5, k: 6))).to eq true
52
+ end
53
+
54
+ it 'supports setting and removing named elements' do
55
+ @l[['a']] = 10
56
+ @l.b = 20
57
+ @l.married = true
58
+ expect(@l[['a']]).to eq 10
59
+ expect(@l.b).to eq 20
60
+ expect(@l.married).to eq true
61
+
62
+ @l.d = nil
63
+ expect(@l.length).to eq 4
64
+ expect(@l[['d']]).to eq nil
65
+ end
66
+ end
67
+
68
+ context 'iteration and richer assignment paths' do
69
+ it 'iterates list elements with each and each_with_index' do
70
+ l = R.list(1, 2, 3, R.list(4, 5, 6))
71
+
72
+ got_each = []
73
+ l.each do |el|
74
+ got_each << (el.is_a?(R::Object) ? el.to_ruby : el)
75
+ end
76
+ expect(got_each).to eq([1, 2, 3, [4, 5, 6]])
77
+
78
+ got_each_idx = []
79
+ l.each_with_index do |el, idx|
80
+ val = el.is_a?(R::Object) ? el.to_ruby : el
81
+ got_each_idx << [idx, val]
82
+ end
83
+ expect(got_each_idx).to eq([[1, 1], [2, 2], [3, 3], [4, [4, 5, 6]]])
84
+ end
85
+
86
+ it 'supports richer add/modify/remove assignment forms' do
87
+ l = R.list(a: 1, b: 2, c: 3, d: R.list(i: 4, j: 5, k: 6))
88
+ l[[1]] = 10
89
+ expect(l[[1]]).to eq 10
90
+
91
+ l[['a']] = 11
92
+ l.b = 22
93
+ l.married = true
94
+ l.number = 5.345
95
+ l.lst = R.list(100, 200)
96
+ l.vec = R.c(500, 600)
97
+
98
+ expect(l[['a']]).to eq 11
99
+ expect(l.b).to eq 22
100
+ expect(l.married).to eq true
101
+ expect(l.number).to eq 5.345
102
+ expect(l.lst).to eq R.list(100, 200)
103
+ expect(l.vec).to eq R.c(500, 600)
104
+
105
+ l.d = nil
106
+ expect(l[['d']]).to eq nil
107
+ l[['vec']] = nil
108
+ expect(l[['vec']]).to eq nil
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe 'NewBridge bulk data.frame pull (column-wise + pull_vector)' do
6
+ it 'unboxes data.frame to Ruby hash with correct columns' do
7
+ df = R.data__frame(x: R.c(1, 2, 3), y: R.c('a', 'b', 'c'))
8
+ ruby = df.to_ruby
9
+ expect(ruby).to be_a(Hash)
10
+ expect(ruby['x']).to eq([1, 2, 3])
11
+ expect(ruby['y']).to eq(%w[a b c])
12
+ end
13
+
14
+ it 'preserves NA in numeric and logical columns' do
15
+ h = R::Support.generate_var_name
16
+ R.bridge.eval_r("#{h} <- data.frame(a = c(1, NA_real_), b = c(TRUE, NA), stringsAsFactors = FALSE)")
17
+ raw = R.bridge.pull_dataframe(h)
18
+ expect(raw['a'][0]).to eq(1.0)
19
+ expect(raw['a'][1]).to be_nil
20
+ expect(raw['b'][0]).to eq(true)
21
+ expect(raw['b'][1]).to eq(R::NA)
22
+ end
23
+
24
+ it 'uses one bulk pull per atomic column (not per cell)' do
25
+ client = R.bridge.instance_variable_get(:@client)
26
+ bulk = 0
27
+ allow(client).to receive(:eval_r).and_wrap_original do |m, code, **kwargs|
28
+ bulk += 1 if code.to_s.start_with?('__G_PULL_VECTOR__')
29
+ m.call(code, **kwargs)
30
+ end
31
+
32
+ df = R.data__frame(u: R.c(10, 20), v: R.c(1.5, 2.5), w: R.c(true, false))
33
+ df.to_ruby
34
+ expect(bulk).to eq(3)
35
+ end
36
+
37
+ it 'matches manual column bind for zero-row data.frame' do
38
+ h = R::Support.generate_var_name
39
+ R.bridge.eval_r("#{h} <- data.frame(x = numeric(0), y = character(0), stringsAsFactors = FALSE)")
40
+ raw = R.bridge.pull_dataframe(h)
41
+ expect(raw['x']).to eq([])
42
+ expect(raw['y']).to eq([])
43
+ end
44
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe 'NewBridge bulk vector pull (__G_PULL_VECTOR__)' do
6
+ it 'pulls full integer vector in one gatekeeper call' do
7
+ client = R.bridge.instance_variable_get(:@client)
8
+ bulk_cmds = []
9
+ allow(client).to receive(:eval_r).and_wrap_original do |m, code, **kwargs|
10
+ bulk_cmds << code.to_s if code.to_s.start_with?('__G_PULL_VECTOR__')
11
+ m.call(code, **kwargs)
12
+ end
13
+
14
+ v = R.c(7, 8, 9)
15
+ arr = v >> nil
16
+ expect(arr).to eq([7, 8, 9])
17
+ expect(bulk_cmds.any? { |c| c =~ /\A__G_PULL_VECTOR__\|g2_v\d+\z/ }).to eq(true)
18
+ end
19
+
20
+ it 'pulls double vector with NA as nil' do
21
+ h = R::Support.generate_var_name
22
+ R.bridge.eval_r("#{h} <- c(1.0, NA_real_, 3.0)")
23
+ arr = R.bridge.pull_vector(h)
24
+ expect(arr[0]).to eq(1.0)
25
+ expect(arr[1]).to be_nil
26
+ expect(arr[2]).to eq(3.0)
27
+ end
28
+
29
+ it 'pulls logical vector with NA mapped to R::NA' do
30
+ v = R.c(true, false, R::NA)
31
+ arr = v >> nil
32
+ expect(arr[0]).to eq(true)
33
+ expect(arr[1]).to eq(false)
34
+ expect(arr[2]).to eq(R::NA)
35
+ end
36
+
37
+ it 'pulls character vector with NA as nil' do
38
+ v = R.c('x', 'y')
39
+ arr = v >> nil
40
+ expect(arr).to eq(%w[x y])
41
+ end
42
+
43
+ it 'matches elementwise pull for medium-length numeric vector' do
44
+ n = 500
45
+ h = R::Support.generate_var_name
46
+ R.bridge.eval_r("#{h} <- 1:#{n}")
47
+ bridge = R.bridge
48
+ bulk = bridge.pull_vector(h)
49
+ elementwise = bridge.send(:pull_vector_elementwise, h)
50
+ expect(bulk.size).to eq(n)
51
+ expect(bulk).to eq(elementwise)
52
+ end
53
+
54
+ it 'pull_integer_vector slice matches elementwise' do
55
+ h = R::Support.generate_var_name
56
+ R.bridge.eval_r("#{h} <- 10:19")
57
+ bridge = R.bridge
58
+ slice = bridge.pull_integer_vector(h, 10, 2, 4)
59
+ expect(slice).to eq([12, 13, 14, 15])
60
+ slow = bridge.send(:pull_integer_vector_elementwise, h, 2, 4)
61
+ expect(slice).to eq(slow)
62
+ end
63
+
64
+ it 'pull_double_vector slice matches elementwise for doubles' do
65
+ h = R::Support.generate_var_name
66
+ R.bridge.eval_r("#{h} <- as.numeric(1:5) + 0.5")
67
+ bridge = R.bridge
68
+ slice = bridge.pull_double_vector(h, 5, 1, 3)
69
+ expect(slice.size).to eq(3)
70
+ slow = bridge.send(:pull_double_vector_elementwise, h, 1, 3)
71
+ expect(slice).to eq(slow)
72
+ end
73
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe 'NewBridge callback timeout configuration' do
6
+ it 'embeds GALAAZ_CALLBACK_TIMEOUT_MS into callback stub wait time' do
7
+ old = ENV['GALAAZ_CALLBACK_TIMEOUT_MS']
8
+ ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = '123456'
9
+
10
+ begin
11
+ stub = R.bridge.register_callback_proc_stub(proc { |_x| nil })
12
+ expect(stub).to include('galaaz_callback_call_phase3')
13
+ expect(stub).to include('123456')
14
+ ensure
15
+ ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = old
16
+ end
17
+ end
18
+
19
+ it 'uses GALAAZ_BRIDGE_TIMEOUT_SEC as default eval timeout' do
20
+ old = ENV['GALAAZ_BRIDGE_TIMEOUT_SEC']
21
+ ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = '321'
22
+
23
+ begin
24
+ client = R.bridge.instance_variable_get(:@client)
25
+ captured = nil
26
+ allow(client).to receive(:eval_r).and_wrap_original do |m, *args, **kwargs|
27
+ captured = kwargs[:timeout]
28
+ m.call(*args, **kwargs)
29
+ end
30
+
31
+ R.bridge.eval_r('1+1')
32
+ expect(captured).to eq(321)
33
+ ensure
34
+ ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = old
35
+ end
36
+ end
37
+
38
+ it 'uses GALAAZ_BRIDGE_TIMEOUT_SEC in session helper evals' do
39
+ old = ENV['GALAAZ_BRIDGE_TIMEOUT_SEC']
40
+ ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = '321'
41
+
42
+ begin
43
+ client = R.bridge.instance_variable_get(:@client)
44
+ captured = nil
45
+ allow(client).to receive(:eval_r).and_wrap_original do |m, *args, **kwargs|
46
+ captured = kwargs[:timeout] if args[0].to_s.include?('galaaz_assign_session')
47
+ m.call(*args, **kwargs)
48
+ end
49
+
50
+ R.bridge.assign_session('spec_session', 'spec_key', '1L')
51
+ expect(captured).to eq(321)
52
+ ensure
53
+ ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = old
54
+ end
55
+ end
56
+
57
+ it 'does not clear callback timeout env when no per-call override is provided' do
58
+ old = ENV['GALAAZ_CALLBACK_TIMEOUT_MS']
59
+ ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = '7200000'
60
+
61
+ begin
62
+ R.with_callback_timeout_ms(nil) { 1 + 1 }
63
+ expect(ENV['GALAAZ_CALLBACK_TIMEOUT_MS']).to eq('7200000')
64
+ ensure
65
+ ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = old
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,55 @@
1
+ require 'galaaz'
2
+
3
+ describe R::NewBridgeAdapter do
4
+ let(:bridge) { R.bridge }
5
+ let(:client) { bridge.instance_variable_get(:@client) }
6
+
7
+ it 'retries in side-effect mode for exact phase1 scalar limitation error' do
8
+ calls = []
9
+ err = NewBridge::SessionClient::RProcessError.new('phase1 requires length-1 scalar')
10
+
11
+ allow(client).to receive(:eval_r).and_wrap_original do |_m, code, **kwargs|
12
+ calls << [code, kwargs]
13
+ if calls.length == 1
14
+ raise err
15
+ else
16
+ { 'kind' => 'integer', 'value' => 0 }
17
+ end
18
+ end
19
+
20
+ result = bridge.eval_r('function(x) { x }')
21
+
22
+ expect(result).to eq('')
23
+ expect(calls.length).to eq(2)
24
+ expect(calls[1][0]).to eq('({ function(x) { x }; 0L })')
25
+ end
26
+
27
+ it 'retries in side-effect mode for exact unsupported type error' do
28
+ calls = []
29
+ err = NewBridge::SessionClient::RProcessError.new('unsupported type')
30
+
31
+ allow(client).to receive(:eval_r).and_wrap_original do |_m, code, **kwargs|
32
+ calls << [code, kwargs]
33
+ if calls.length == 1
34
+ raise err
35
+ else
36
+ { 'kind' => 'integer', 'value' => 0 }
37
+ end
38
+ end
39
+
40
+ result = bridge.eval_r('x <- c(1,2,3)')
41
+
42
+ expect(result).to eq('')
43
+ expect(calls.length).to eq(2)
44
+ expect(calls[1][0]).to eq('({ x <- c(1,2,3); 0L })')
45
+ end
46
+
47
+ it 'does not swallow unrelated RProcessError even with similar words' do
48
+ err = NewBridge::SessionClient::RProcessError.new('Error: unrelated unsupported type mismatch on user code')
49
+ allow(client).to receive(:eval_r).and_raise(err)
50
+
51
+ expect do
52
+ bridge.eval_r('stop("boom")')
53
+ end.to raise_error(NewBridge::SessionClient::RProcessError, /unrelated unsupported type mismatch/)
54
+ end
55
+ end
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Specs for NilClass#is__null and #isTRUE (R NULL becomes Ruby nil; calling
3
+ # .is__null or .isTRUE on nil must not raise and must behave like R's is.null(NULL) / isTRUE(NULL)).
4
+ #
5
+ # Run with: bin/run_rspec specs/nil_null_spec.rb
6
+ # (plain jruby rspec needs JVM flags; use bin/run_rspec, bin/galaaz-jruby, or GALAAZ_JRUBY_OPTS — see lib/galaaz_jruby.rb)
7
+
8
+ require 'galaaz'
9
+
10
+ describe "NilClass when used as R NULL (missing list element → Ruby nil)" do
11
+
12
+ context "nil.is__null" do
13
+ it "does not raise" do
14
+ expect { nil.is__null }.not_to raise_error
15
+ end
16
+
17
+ it "returns an object that responds to unboxed_get" do
18
+ expect(nil.is__null).to respond_to(:unboxed_get)
19
+ end
20
+
21
+ it "unboxed_get(0) returns true (nil is treated as null)" do
22
+ expect(nil.is__null.unboxed_get(0)).to eq true
23
+ end
24
+ end
25
+
26
+ context "nil.isTRUE" do
27
+ it "does not raise" do
28
+ expect { nil.isTRUE }.not_to raise_error
29
+ end
30
+
31
+ it "unboxed_get(0) returns false (R's isTRUE(NULL) is FALSE)" do
32
+ expect(nil.isTRUE.unboxed_get(0)).to eq false
33
+ end
34
+ end
35
+
36
+ context "nil.is__null | nil.isTRUE (as in include_engine)" do
37
+ it "does not raise and unboxed_get(0) is true" do
38
+ result = (nil.is__null | nil.isTRUE).unboxed_get(0)
39
+ expect(result).to eq true
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Phase 2 (performance): Object.build prefers wrapper_tag / r_class; class() probe only as fallback.
4
+
5
+ require 'galaaz'
6
+
7
+ describe 'R::Object.build (Phase 2 — envelope metadata vs class probe)' do
8
+ describe '.build_class_probe_count' do
9
+ it 'does not probe when r_class and wrapper_tag come from eval_r_with_result envelope' do
10
+ vn = R::Support.generate_var_name
11
+ env = R.bridge.eval_r_with_result("#{vn} <- c(1L, 2L, 3L)")
12
+ expect(env[:type]).to eq(:handle)
13
+ expect(env[:wrapper_tag]).to eq('vector')
14
+
15
+ R::Object.reset_build_counters!
16
+ obj = R::Object.build(env[:handle], nil, r_class: env[:r_class], wrapper_tag: env[:wrapper_tag])
17
+ expect(obj).to be_a(R::Vector)
18
+ expect(R::Object.build_class_probe_count).to eq(0)
19
+ end
20
+
21
+ it 'does not probe when only r_class is set (legacy envelope)' do
22
+ vn = R::Support.generate_var_name
23
+ env = R.bridge.eval_r_with_result("#{vn} <- list(a = 1L)")
24
+ expect(env[:type]).to eq(:handle)
25
+
26
+ R::Object.reset_build_counters!
27
+ obj = R::Object.build(env[:handle], nil, r_class: env[:r_class], wrapper_tag: nil)
28
+ expect(obj).to be_a(R::List)
29
+ expect(R::Object.build_class_probe_count).to eq(0)
30
+ end
31
+
32
+ it 'probes once when neither r_class nor a non-other wrapper_tag is given' do
33
+ vn = R::Support.generate_var_name
34
+ R.bridge.eval_r("#{vn} <- c(10L, 20L)")
35
+
36
+ R::Object.reset_build_counters!
37
+ obj = R::Object.build(vn)
38
+ expect(obj).to be_a(R::Vector)
39
+ expect(R::Object.build_class_probe_count).to eq(1)
40
+ end
41
+
42
+ it 'uses r_class for wrapper_tag other without probing (e.g. expression)' do
43
+ vn = R::Support.generate_var_name
44
+ env = R.bridge.eval_r_with_result("#{vn} <- expression(1 + 2)")
45
+ expect(env[:wrapper_tag]).to eq('other')
46
+
47
+ R::Object.reset_build_counters!
48
+ obj = R::Object.build(vn, nil, r_class: env[:r_class], wrapper_tag: env[:wrapper_tag])
49
+ expect(obj).to be_a(R::RExpression)
50
+ expect(R::Object.build_class_probe_count).to eq(0)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Phase 1 (plan): NewBridge callback argument transport + semantic return via galaaz_bridge_env.
4
+ # Fast suite — keep coverage here, not in new_bridge_specs.
5
+
6
+ require 'galaaz'
7
+
8
+ describe 'Phase 1 NewBridge callbacks (adapter proc stub)' do
9
+ def global_callback_handles
10
+ names = R::Support.eval("ls(envir = .GlobalEnv, pattern = '^g2_v[0-9]+$')")
11
+ ruby = names.respond_to?(:to_ruby) ? names.to_ruby : []
12
+ ruby.is_a?(Array) ? ruby : Array(ruby).compact
13
+ end
14
+
15
+ before(:all) do
16
+ R.bridge.eval_r('call_with_arg <- function(f, x) { f(x) }')
17
+ R.bridge.eval_r('call_twice <- function(f, a, b) { f(a); f(b) }')
18
+ end
19
+
20
+ it 'passes numeric scalar and returns semantic value from R' do
21
+ result = R.call_with_arg(proc { |x| (x >> 0) + 1 }, 41)
22
+ expect(result).to be_a(R::Object)
23
+ expect(result.to_ruby).to eq(42.0)
24
+ end
25
+
26
+ it 'passes character scalar' do
27
+ result = R.call_with_arg(proc { |x| x.to_ruby.to_s.upcase == 'ABC' ? 1 : 0 }, 'abc')
28
+ expect(result.to_ruby).to eq(1.0)
29
+ end
30
+
31
+ it 'passes logical scalar' do
32
+ result = R.call_with_arg(proc { |x| x.to_ruby == true ? 7 : 0 }, true)
33
+ expect(result.to_ruby).to eq(7.0)
34
+ end
35
+
36
+ it 'passes logical NA (R NA may appear as Ruby nil at the callback boundary)' do
37
+ na1 = R::Support.eval('NA')
38
+ result = R.call_with_arg(proc { |x|
39
+ (x.nil? || (x.respond_to?(:to_ruby) && x.to_ruby.nil?)) ? 1 : 0
40
+ }, na1)
41
+ expect(result.to_ruby).to eq(1.0)
42
+ end
43
+
44
+ it 'passes non-scalar argument as boxed R object' do
45
+ result = R.call_with_arg(proc { |x| (x.length >> 0) == 3 ? 1 : 0 }, R.c(1, 2, 3))
46
+ expect(result.to_ruby).to eq(1.0)
47
+ end
48
+
49
+ it 'reuses the same callback for two invocations' do
50
+ result = R.call_twice(proc { |x| (x >> 0) + 100 }, 1, 2)
51
+ expect(result).to be_a(R::Object)
52
+ # Last invocation wins as return value of call_twice (f(b) with b=2 -> 102)
53
+ expect(result.to_ruby).to eq(102.0)
54
+ end
55
+
56
+ it 'isolates two different callback procs' do
57
+ r1 = R.call_with_arg(proc { |x| (x >> 0) + 1 }, 10)
58
+ r2 = R.call_with_arg(proc { |x| (x >> 0) + 2 }, 10)
59
+ expect(r1.to_ruby).to eq(11.0)
60
+ expect(r2.to_ruby).to eq(12.0)
61
+ end
62
+
63
+ it 'does not leak temporary g2_v callback handles in .GlobalEnv' do
64
+ before = global_callback_handles
65
+
66
+ 10.times do |i|
67
+ out = R.call_with_arg(proc { |x| (x >> 0) + 1 }, i)
68
+ expect(out.to_ruby).to eq((i + 1).to_f)
69
+ end
70
+
71
+ after = global_callback_handles
72
+ expect(after).to eq(before)
73
+ end
74
+
75
+ it 'does not create legacy galaaz_bridge_env for callback semantic returns' do
76
+ R::Support.eval("if (exists('galaaz_bridge_env', envir = .GlobalEnv, inherits = FALSE)) rm('galaaz_bridge_env', envir = .GlobalEnv)")
77
+
78
+ out = R.call_with_arg(proc { |x| (x >> 0) + 1 }, 9)
79
+ expect(out.to_ruby).to eq(10.0)
80
+
81
+ exists_legacy = R::Support.eval("exists('galaaz_bridge_env', envir = .GlobalEnv, inherits = FALSE)")
82
+ expect(exists_legacy).to eq(false)
83
+ end
84
+ end