rice 4.11.0 → 4.11.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1cb911ca5d8bdd05beb12475ede38818ab53bf0af2724fb2268c7df15b10a8d
4
- data.tar.gz: dd9c953afcee173cfe9970b34dc9b91d8de5e5adf29efb262805edadad850fdb
3
+ metadata.gz: 935f187922d58bf0dc585e30ae66b5454bb8f87ac8c640ca38d9445371991dff
4
+ data.tar.gz: d00d336620c52f7e3a56941d6402109bcc20d3a73dc4090fd3d49395cbbdc7e7
5
5
  SHA512:
6
- metadata.gz: cb66c85d175f289facdf8058d3e87cc7be957082e11cf769f2328cd175b83263733b52b8f0b5378bfb43a2244db6bf7507875bd616adacc772c317aeedd6a53a
7
- data.tar.gz: a70fe6bdfe219aac33d3645987f1bfc9bb9e1eb6dea3dc5daa6e525a4835ac0622d460518f41c46585bd5afabceb5096a027f68b1584193aded8e54995892f37
6
+ metadata.gz: 9c006c97da6e586d836a08b51c2d1ed37e8921e11f0dc30f45d3fcfeb5166ae5172610b958e0b9fe35a8eddb199af05b88eec1bf272541b7a39d890b0856bacf
7
+ data.tar.gz: 7795809caf1d34330279d5fb454cb935b08422b531522d721d4ba3185442426d51fd1f8795dfbbbb34daff9a19d586e0e5554925d69eed7d57aebcbba9017a6a
data/CHANGELOG.md CHANGED
@@ -1,14 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.11.1 (2026-02-18)
4
+
5
+ ### Enhancements
6
+
7
+ * Be more lenient on wrapp Qnil values in the C++ API
8
+
9
+
3
10
  ## 4.11.0 (2026-02-17)
4
11
 
5
- Enhancements:
6
- This release focuses on improving memory management:
12
+ This release focuses on improving memory management.
13
+
14
+ ### Enhancements
15
+
7
16
  * C++ API is now GC safe
8
17
  * C++ API wrappers no longer default to rb_cObject, avoiding unintended Object changes
9
- * Enable Instance Registry for Ruby owned C++ objects to avoid double frees
18
+ * Enable Instance Registry for Ruby owned C++ objects to avoid double frees
19
+
20
+ ### Breaking Changes
10
21
 
11
- Incompatible Changes:
12
22
  * `InstanceRegistry.isEnabled` (boolean) has been replaced by an `InstanceRegistry.isEnabled` which is an enum (`Off`, `Owned`, `All`).
13
23
  * `InstanceRegistry` now defaults to `Owned` - previously it was disabled. The goal of this change is to ensure C++ objects owned by Ruby are only wrapped once to avoid double free errors.
14
24
  * `Object()` now defaults to `Qnil` instead of `rb_cObject`. This avoids accidentally manipulating `rb_cObject` when a wrapper is not explicitly initialized. Calling methods on wrappers that point to `Qnil` will generally raise an exception. Use `object.is_nil()` to check for `nil` before using a wrapper as a receiver.
@@ -19,7 +29,8 @@ Incompatible Changes:
19
29
 
20
30
  ## 4.10.0 (2026-02-07)
21
31
 
22
- Enhancements:
32
+ ### Enhancements
33
+
23
34
  * Ruby 4.0 support
24
35
  * Support incomplete types (PIMPL/opaque handle patterns). Rice now uses `typeid(T*)` for forward-declared types that are never fully defined.
25
36
  * Support `noexcept` functions, static members, and static member functions
@@ -28,12 +39,11 @@ Enhancements:
28
39
  * Add `std::ostream`, `std::ostringstream`, and `std::ofstream`. Ruby can write to C++ streams and pass them to C++ functions. Standard streams are exposed as `Std::COUT` and `Std::CERR`.
29
40
  * Support verifying arrays of non-fundamental types (e.g., `MyClass[2]`)
30
41
  * Delegate method calls for smart pointers to their wrapped objects via method_missing?
31
-
32
- Internal:
33
42
  * Refactor type handling by merging `TypeMapper` into `TypeDetail` and simplifying class hierarchy
34
43
  * Greatly simplify define_attr
35
44
 
36
- Incompatible Changes:
45
+ ### Breaking Changes
46
+
37
47
  * `Address_Registration_Guard` has been replaced by `Pin`. If you are using `Address_Registration_Guard`
38
48
  to protect Ruby VALUEs from garbage collection, update your code to use `Pin` instead:
39
49
 
@@ -67,15 +77,18 @@ Incompatible Changes:
67
77
  * The `Data_Type<T>::define()` method has been removed. See the [Class Templates](bindings/class_templates.md) documentation for the recommended approach.
68
78
 
69
79
  ## 4.9.1 (2026-01-04)
80
+
70
81
  This release focuses on improving memory management for STL containers and attribute setters.
71
82
 
72
- Enhancements:
83
+ ### Enhancements
84
+
73
85
  * Support `takeOwnership` and `keepAlive` when setting attributes via `Arg("value").takeOwnership()` and `Arg("value").keepAlive()`
74
86
  * Add `Arg` parameter names to all STL container methods for keyword argument support
75
87
  * Add `keepAlive` support for STL container operations (vector push/insert, set insert, map/multimap store)
76
88
  * Add `keepAlive` for map/unordered_map/multimap keys to prevent GC of pointer-type keys
77
89
 
78
- Bug Fixes:
90
+ ### Fixes
91
+
79
92
  * Fix error when multiple overloaded methods take different types of vectors
80
93
  * Fix type unknown errors when using `std::shared_ptr` with g++
81
94
  * Fix CMake `_Ruby_DLEXT` variable type (string, not path)
@@ -83,6 +96,7 @@ Bug Fixes:
83
96
  * Fix incorrect attribute overloading behavior
84
97
 
85
98
  ## 4.9.0 (2026-01-01)
99
+
86
100
  This release revamps smart pointer support for `std::shared_ptr` and `std::unique_ptr`.
87
101
 
88
102
  Rice now always creates wrapper classes for smart pointers under the `Std` module (e.g., `Std::SharedPtr≺MyClass≻`, `Std::UniquePtr≺MyClass≻`). These wrapper classes expose methods like `empty?`, `get`, `swap`, and for shared_ptr, `use_count`. Methods defined on the managed type are automatically forwarded to the wrapper class using Ruby's `Forwardable` module.
@@ -90,7 +104,10 @@ Rice now always creates wrapper classes for smart pointers under the `Std` modul
90
104
  This change is backwards compatible for Ruby code but not C++ code. If you have implemented your own Smart Pointer wrapper then please read the Smart Pointer documentation for more information on how to update it.
91
105
 
92
106
  ## 4.8.0 (2025-12-29)
93
- This release focuses on making Rice easier to use:
107
+
108
+ This release focuses on making Rice easier to use.
109
+
110
+ ### Enhancements
94
111
 
95
112
  * Compilation times are approximately 2x faster than version 4.7
96
113
  * Compiled library sizes are about 30% smaller
@@ -108,7 +125,7 @@ This release focuses on making Rice easier to use:
108
125
  * Fixed Ruby detection for Homebrew installations on macOS
109
126
  * Added support for references to fundamental types
110
127
 
111
- However, these changes did require some breaking changes, which include:
128
+ ### Breaking Changes
112
129
 
113
130
  * `Return().isBuffer()` is replaced by `ReturnBuffer()`
114
131
  * `Arg("").isBuffer()` is replaced by `ArgBuffer("")`
@@ -117,13 +134,17 @@ However, these changes did require some breaking changes, which include:
117
134
  * All function/method parameter default values are verified. You may see errors like "ArgumentError: Type is not registered with Rice" or "Invalid AnyCast". In either case, make sure to check that specified default values are correct.
118
135
 
119
136
  ## 4.7.1 (2025-10-28)
120
- Updates:
137
+
138
+ ### Enhancements
139
+
121
140
  * Update overload resolution to take into account function arguments that are tagged as buffers via Arg("").setBuffer().
122
141
  * Make second parameter optional for Array#push and update docs
123
142
  * Remove ostruct runtime dependency
124
143
 
125
144
  ## 4.7.0 (2025-10-22)
126
- Updates:
145
+
146
+ ### Enhancements
147
+
127
148
  * Refactor Native wrappers - functions, methods, attributes and procs - to enable introspection API
128
149
  * Introduce Pointer<T> class to wrap pointers to fundamental types and arrays.
129
150
  * Add new methods Arg#setBuffer and Return#setBuffer to indicate that a C++ pointer references an array of objects versus a single object
@@ -141,13 +162,14 @@ Updates:
141
162
  * Correctly encode UTF8 Ruby class names in exception messages
142
163
  * Add support for disabling Ruby's global interpreter lock (GIL) when calling native functions
143
164
 
144
- Breaking Changes:
165
+ ### Breaking Changes
166
+
145
167
  * Custom implementations of From_Ruby must include a custom constructor:
146
- ```
168
+ ```cpp
147
169
  explicit From_Ruby(Arg* arg)
148
170
  ```
149
171
  * Custom implementations of To_Ruby must include a custom constructor:
150
- ```
172
+ ```cpp
151
173
  explicit To_Ruby(Return* returnInfo)
152
174
  ```
153
175
  * You can no longer pass a Buffer<T> to an API that takes a pointer. Instead use Buffer<T>#data or Buffer<T>::release
@@ -155,6 +177,7 @@ Breaking Changes:
155
177
  * Array#push requires a second argument.
156
178
 
157
179
  ## 4.6.1 (2025-06-25)
180
+
158
181
  * Improve attribute handling. Correctly deal with non-copyable/assignable attributes and return references instead of copies of objects
159
182
  * Improve Buffer implementation to deal with 4 cases:
160
183
  - array of fundamental types (int*)
@@ -165,6 +188,7 @@ Breaking Changes:
165
188
  * Fix header check on Ubuntu 22.04
166
189
 
167
190
  ## 4.6.0 (2025-06-09)
191
+
168
192
  Rice 4.6 is a major release that adds significant new functionality based on wrapping the OpenCV library, including:
169
193
 
170
194
  * Add a new Buffer class to provide Ruby API support for pointers sent to or returned by C++
@@ -188,6 +212,7 @@ Rice 4.6 is a major release that adds significant new functionality based on wra
188
212
  * Make Enums more useful by adding coerce method to enable stringing together bitwise operators - for example Season::Winter | Season::Spring | Season::Summer.
189
213
 
190
214
  ## 4.5 (2025-02-09)
215
+
191
216
  Rice 4.5 is a major release that adds significant new functionality, including:
192
217
 
193
218
  * Support method overloading
@@ -195,7 +220,7 @@ Rice 4.5 is a major release that adds significant new functionality, including:
195
220
  * Support rvalues
196
221
  * Support using keyword arguments in Ruby to call C++ methods
197
222
  * Support C style callbacks, including adding a new define_callback method
198
- * Support wrapping C/C++ functions as Ruby procs
223
+ * Support wrapping C/C++ functions as Ruby procs
199
224
  * Support calling methods that take pointers
200
225
  * Add Data_Type#define method to more easily support C++ template classes
201
226
  * Adds #define_constant method
@@ -261,7 +286,7 @@ Rice 4.1 builds on the 4.0 release and has a number of improvements that both po
261
286
 
262
287
  * Exception handlers are now registered globally versus per module. This requires updating code that calls Class#add_handler to use register_handler instead.
263
288
  * Rename Arg#isValue to Arg#setValue and then Arg#getIsValue to Arg#isValue
264
- * Rename Return#isValue to Return#setValue and Return#getIsValue to Return#isValue
289
+ * Rename Return#isValue to Return#setValue and Return#getIsValue to Return#isValue
265
290
 
266
291
  New or improved functionality includes:
267
292
 
@@ -284,7 +309,6 @@ New or improved functionality includes:
284
309
 
285
310
  Rice also includes experimental support for instance tracking so that Rice maps the same C++ instance to the same Ruby instance each time it is passed to Ruby. See the documentation for more information.
286
311
 
287
-
288
312
  ## 4.0 (2021-4-8)
289
313
 
290
314
  Rice 4.0 is a significant change from 3.0 and has multiple backwards-incompatible
@@ -330,10 +354,10 @@ There are a ton of changes, but some of the most important ones:
330
354
 
331
355
  ## 2.1.0 (2016-1-1)
332
356
 
333
- * Fix compliation issues related to g++ and Ruby 2.3.0
357
+ * Fix compliation issues related to g++ and Ruby 2.3.0.
334
358
  To do this, I had to remove Array::to_c_array which was exposing the internals of a
335
- Ruby RArray type to the system. This is not something that we should support going forward
336
- as these internals are going to change.
359
+ Ruby RArray type to the system. This is not something that we should support going forward
360
+ as these internals are going to change.
337
361
 
338
362
  ## 2.0.0 (2015-11-27)
339
363
 
@@ -350,7 +374,7 @@ There are a ton of changes, but some of the most important ones:
350
374
 
351
375
  ## 1.7.0 (2015-1-6)
352
376
 
353
- * Ruby 2.2 support
377
+ * Ruby 2.2 support.
354
378
  Potential breaking changes. Ruby 2.2 removed RHash as a public accessible struct
355
379
  and as such I changed all of the Builtin_Objects to work directly off of RObject
356
380
  instead of the specifics (RArray, RStruct, RString, etc). If you've been using these
@@ -1859,6 +1859,12 @@ namespace Rice
1859
1859
  Object(Object&& other) = default;
1860
1860
  Object& operator=(Object&& other) = default;
1861
1861
 
1862
+ //! Implicit conversion to VALUE.
1863
+ operator VALUE() const;
1864
+
1865
+ //! Explicitly get the encapsulated VALUE.
1866
+ VALUE value() const;
1867
+
1862
1868
  //! Returns false if the object is nil or false; returns true
1863
1869
  //! otherwise.
1864
1870
  explicit operator bool() const;
@@ -1866,11 +1872,6 @@ namespace Rice
1866
1872
  //! Returns true if the object is nil, false otherwise.
1867
1873
  bool is_nil() const;
1868
1874
 
1869
- //! Implicit conversion to VALUE.
1870
- operator VALUE() const;
1871
-
1872
- //! Explicitly get the encapsulated VALUE.
1873
- VALUE value() const;
1874
1875
 
1875
1876
  //! Get the class of an object.
1876
1877
  /*! \return the object's Class.
@@ -2071,6 +2072,10 @@ namespace Rice
2071
2072
  void remove_const(Identifier name);
2072
2073
 
2073
2074
  protected:
2075
+ //! Checks the encapsulated VALUE is not nil and returns it. If it is nil
2076
+ //! an exception is thrown.
2077
+ VALUE validated_value() const;
2078
+
2074
2079
  //! Set the encapsulated value.
2075
2080
  void set_value(VALUE value);
2076
2081
 
@@ -2700,7 +2705,7 @@ namespace Rice
2700
2705
  */
2701
2706
  inline auto& include_module(Module const& inc)
2702
2707
  {
2703
- detail::protect(rb_include_module, this->value(), inc.value());
2708
+ detail::protect(rb_include_module, this->validated_value(), inc.value());
2704
2709
  return *this;
2705
2710
  }
2706
2711
 
@@ -2724,7 +2729,7 @@ inline auto& include_module(Module const& inc)
2724
2729
  template<typename Method_T, typename...Arg_Ts>
2725
2730
  inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
2726
2731
  {
2727
- this->wrap_native_method(this->value(), name, std::forward<Method_T>(method), args...);
2732
+ this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
2728
2733
  return *this;
2729
2734
  }
2730
2735
 
@@ -2742,7 +2747,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
2742
2747
  template<typename Function_T, typename...Arg_Ts>
2743
2748
  inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
2744
2749
  {
2745
- this->wrap_native_function(this->value(), name, std::forward<Function_T>(func), args...);
2750
+ this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
2746
2751
  return *this;
2747
2752
  }
2748
2753
 
@@ -2816,7 +2821,7 @@ template<typename Constant_T>
2816
2821
  inline auto& define_constant(std::string name, Constant_T value)
2817
2822
  {
2818
2823
  using Base_T = detail::remove_cv_recursive_t<Constant_T>;
2819
- detail::protect(rb_define_const, this->value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
2824
+ detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
2820
2825
  return *this;
2821
2826
  }
2822
2827
  protected:
@@ -2898,7 +2903,7 @@ namespace Rice
2898
2903
  */
2899
2904
  inline auto& include_module(Module const& inc)
2900
2905
  {
2901
- detail::protect(rb_include_module, this->value(), inc.value());
2906
+ detail::protect(rb_include_module, this->validated_value(), inc.value());
2902
2907
  return *this;
2903
2908
  }
2904
2909
 
@@ -2922,7 +2927,7 @@ inline auto& include_module(Module const& inc)
2922
2927
  template<typename Method_T, typename...Arg_Ts>
2923
2928
  inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
2924
2929
  {
2925
- this->wrap_native_method(this->value(), name, std::forward<Method_T>(method), args...);
2930
+ this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
2926
2931
  return *this;
2927
2932
  }
2928
2933
 
@@ -2940,7 +2945,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
2940
2945
  template<typename Function_T, typename...Arg_Ts>
2941
2946
  inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
2942
2947
  {
2943
- this->wrap_native_function(this->value(), name, std::forward<Function_T>(func), args...);
2948
+ this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
2944
2949
  return *this;
2945
2950
  }
2946
2951
 
@@ -3014,7 +3019,7 @@ template<typename Constant_T>
3014
3019
  inline auto& define_constant(std::string name, Constant_T value)
3015
3020
  {
3016
3021
  using Base_T = detail::remove_cv_recursive_t<Constant_T>;
3017
- detail::protect(rb_define_const, this->value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
3022
+ detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
3018
3023
  return *this;
3019
3024
  }
3020
3025
  };
@@ -3363,7 +3368,7 @@ namespace Rice
3363
3368
  */
3364
3369
  inline auto& include_module(Module const& inc)
3365
3370
  {
3366
- detail::protect(rb_include_module, this->value(), inc.value());
3371
+ detail::protect(rb_include_module, this->validated_value(), inc.value());
3367
3372
  return *this;
3368
3373
  }
3369
3374
 
@@ -3387,7 +3392,7 @@ inline auto& include_module(Module const& inc)
3387
3392
  template<typename Method_T, typename...Arg_Ts>
3388
3393
  inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
3389
3394
  {
3390
- this->wrap_native_method(this->value(), name, std::forward<Method_T>(method), args...);
3395
+ this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
3391
3396
  return *this;
3392
3397
  }
3393
3398
 
@@ -3405,7 +3410,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
3405
3410
  template<typename Function_T, typename...Arg_Ts>
3406
3411
  inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
3407
3412
  {
3408
- this->wrap_native_function(this->value(), name, std::forward<Function_T>(func), args...);
3413
+ this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
3409
3414
  return *this;
3410
3415
  }
3411
3416
 
@@ -3479,7 +3484,7 @@ template<typename Constant_T>
3479
3484
  inline auto& define_constant(std::string name, Constant_T value)
3480
3485
  {
3481
3486
  using Base_T = detail::remove_cv_recursive_t<Constant_T>;
3482
- detail::protect(rb_define_const, this->value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
3487
+ detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
3483
3488
  return *this;
3484
3489
  }
3485
3490
  protected:
@@ -4527,6 +4532,10 @@ namespace Rice::detail
4527
4532
  T defaultValue = this->arg()->template defaultValue<T>();
4528
4533
  return this->toRuby_.convert(defaultValue);
4529
4534
  }
4535
+ else
4536
+ {
4537
+ throw std::runtime_error("Default value not allowed for parameter " + this->arg()->name);
4538
+ }
4530
4539
  }
4531
4540
  else
4532
4541
  {
@@ -12568,16 +12577,9 @@ namespace Rice
12568
12577
  {
12569
12578
  }
12570
12579
 
12571
- inline Object::operator bool() const
12572
- {
12573
- // Bypass getter to not raise exception
12574
- return RTEST(this->value_.value());
12575
- }
12576
-
12577
- inline bool Object::is_nil() const
12580
+ inline VALUE Object::value() const
12578
12581
  {
12579
- // Bypass getter to not raise exception
12580
- return NIL_P(this->value_.value());
12582
+ return this->value_.value();
12581
12583
  }
12582
12584
 
12583
12585
  inline Object::operator VALUE() const
@@ -12585,9 +12587,9 @@ namespace Rice
12585
12587
  return this->value();
12586
12588
  }
12587
12589
 
12588
- inline VALUE Object::value() const
12590
+ inline VALUE Object::validated_value() const
12589
12591
  {
12590
- VALUE result = this->value_.value();
12592
+ VALUE result = this->value();
12591
12593
 
12592
12594
  if (result == Qnil)
12593
12595
  {
@@ -12598,6 +12600,16 @@ namespace Rice
12598
12600
  return result;
12599
12601
  }
12600
12602
 
12603
+ inline Object::operator bool() const
12604
+ {
12605
+ return RTEST(this->value());
12606
+ }
12607
+
12608
+ inline bool Object::is_nil() const
12609
+ {
12610
+ return NIL_P(this->value());
12611
+ }
12612
+
12601
12613
  template<typename ...Parameter_Ts>
12602
12614
  inline Object Object::call(Identifier id, Parameter_Ts... args) const
12603
12615
  {
@@ -12609,7 +12621,7 @@ namespace Rice
12609
12621
  easy to duplicate by setting GC.stress to true and calling a constructor
12610
12622
  that takes multiple values like a std::pair wrapper. */
12611
12623
  std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(std::forward<Parameter_Ts>(args))... };
12612
- return detail::protect(rb_funcallv, value(), id.id(), (int)values.size(), (const VALUE*)values.data());
12624
+ return detail::protect(rb_funcallv, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data());
12613
12625
  }
12614
12626
 
12615
12627
  template<typename ...Parameter_Ts>
@@ -12617,13 +12629,13 @@ namespace Rice
12617
12629
  {
12618
12630
  /* IMPORTANT - See call() above */
12619
12631
  std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(args)... };
12620
- return detail::protect(rb_funcallv_kw, value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
12632
+ return detail::protect(rb_funcallv_kw, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
12621
12633
  }
12622
12634
 
12623
12635
  template<typename T>
12624
12636
  inline void Object::iv_set(Identifier name, T const& value)
12625
12637
  {
12626
- detail::protect(rb_ivar_set, this->value(), name.id(), detail::To_Ruby<T>().convert(value));
12638
+ detail::protect(rb_ivar_set, this->validated_value(), name.id(), detail::To_Ruby<T>().convert(value));
12627
12639
  }
12628
12640
 
12629
12641
  inline int Object::compare(Object const& other) const
@@ -12639,66 +12651,71 @@ namespace Rice
12639
12651
  return this->is_nil() && other.is_nil();
12640
12652
  }
12641
12653
 
12642
- VALUE result = detail::protect(rb_equal, this->value(), other.value());
12654
+ VALUE result = detail::protect(rb_equal, this->validated_value(), other.validated_value());
12643
12655
  return RB_TEST(result);
12644
12656
  }
12645
12657
 
12646
12658
  inline bool Object::is_eql(const Object& other) const
12647
12659
  {
12648
- VALUE result = detail::protect(rb_eql, this->value(), other.value());
12660
+ if (this->is_nil() || other.is_nil())
12661
+ {
12662
+ return this->is_nil() && other.is_nil();
12663
+ }
12664
+
12665
+ VALUE result = detail::protect(rb_eql, this->validated_value(), other.validated_value());
12649
12666
  return RB_TEST(result);
12650
12667
  }
12651
12668
 
12652
12669
  inline void Object::freeze()
12653
12670
  {
12654
- detail::protect(rb_obj_freeze, value());
12671
+ detail::protect(rb_obj_freeze, this->validated_value());
12655
12672
  }
12656
12673
 
12657
12674
  inline bool Object::is_frozen() const
12658
12675
  {
12659
- return RB_OBJ_FROZEN(value());
12676
+ return RB_OBJ_FROZEN(this->validated_value());
12660
12677
  }
12661
12678
 
12662
12679
  inline int Object::rb_type() const
12663
12680
  {
12664
- return ::rb_type(this->value());
12681
+ return ::rb_type(this->validated_value());
12665
12682
  }
12666
12683
 
12667
12684
  inline VALUE Object::object_id() const
12668
12685
  {
12669
- return detail::protect(rb_obj_id, this->value());
12686
+ return detail::protect(rb_obj_id, this->validated_value());
12670
12687
  }
12671
12688
 
12672
12689
  inline bool Object::is_a(Object klass) const
12673
12690
  {
12674
- VALUE result = detail::protect(rb_obj_is_kind_of, this->value(), klass.value());
12691
+ VALUE result = detail::protect(rb_obj_is_kind_of, this->validated_value(), klass.validated_value());
12675
12692
  return RB_TEST(result);
12676
12693
  }
12677
12694
 
12678
12695
  inline void Object::extend(Module const& mod)
12679
12696
  {
12680
- detail::protect(rb_extend_object, this->value(), mod.value());
12697
+ detail::protect(rb_extend_object, this->validated_value(), mod.validated_value());
12681
12698
  }
12682
12699
 
12683
12700
  inline bool Object::respond_to(Identifier id) const
12684
12701
  {
12685
- return bool(rb_respond_to(this->value(), id.id()));
12702
+ return bool(rb_respond_to(this->validated_value(), id.id()));
12686
12703
  }
12687
12704
 
12688
12705
  inline bool Object::is_instance_of(Object klass) const
12689
12706
  {
12690
- VALUE result = detail::protect(rb_obj_is_instance_of, this->value(), klass.value());
12707
+ VALUE result = detail::protect(rb_obj_is_instance_of, this->validated_value(), klass.validated_value());
12691
12708
  return RB_TEST(result);
12692
12709
  }
12693
12710
 
12694
12711
  inline Object Object::iv_get(Identifier name) const
12695
12712
  {
12696
- return detail::protect(rb_ivar_get, this->value(), name.id());
12713
+ return detail::protect(rb_ivar_get, this->validated_value(), name.id());
12697
12714
  }
12698
12715
 
12699
12716
  inline Object Object::attr_get(Identifier name) const
12700
12717
  {
12701
- return detail::protect(rb_attr_get, this->value(), name.id());
12718
+ return detail::protect(rb_attr_get, this->validated_value(), name.id());
12702
12719
  }
12703
12720
 
12704
12721
  inline void Object::set_value(VALUE value)
@@ -12708,20 +12725,20 @@ namespace Rice
12708
12725
 
12709
12726
  inline Object Object::const_get(Identifier name) const
12710
12727
  {
12711
- return detail::protect(rb_const_get, this->value(), name.id());
12728
+ return detail::protect(rb_const_get, this->validated_value(), name.id());
12712
12729
  }
12713
12730
 
12714
12731
  inline bool Object::const_defined(Identifier name) const
12715
12732
  {
12716
- size_t result = detail::protect(rb_const_defined, this->value(), name.id());
12733
+ size_t result = detail::protect(rb_const_defined, this->validated_value(), name.id());
12717
12734
  return bool(result);
12718
12735
  }
12719
12736
 
12720
12737
  inline Object Object::const_set(Identifier name, Object value)
12721
12738
  {
12722
12739
  // We will allow setting constants to Qnil, or the decimal value of 4. This happens
12723
- // in C++ libraries with enums. Thus skip the value() method that raises excptions
12724
- detail::protect(rb_const_set, this->value(), name.id(), value.value_.value());
12740
+ // in C++ libraries with enums. Thus use value() instead of validated_value
12741
+ detail::protect(rb_const_set, this->validated_value(), name.id(), value.value());
12725
12742
  return value;
12726
12743
  }
12727
12744
 
@@ -12736,7 +12753,7 @@ namespace Rice
12736
12753
 
12737
12754
  inline void Object::remove_const(Identifier name)
12738
12755
  {
12739
- detail::protect(rb_mod_remove_const, this->value(), name.to_sym());
12756
+ detail::protect(rb_mod_remove_const, this->validated_value(), name.to_sym());
12740
12757
  }
12741
12758
 
12742
12759
  inline bool operator==(Object const& lhs, Object const& rhs)
@@ -12898,22 +12915,22 @@ namespace Rice
12898
12915
 
12899
12916
  inline size_t String::length() const
12900
12917
  {
12901
- return RSTRING_LEN(value());
12918
+ return RSTRING_LEN(this->value());
12902
12919
  }
12903
12920
 
12904
12921
  inline char String::operator[](ptrdiff_t index) const
12905
12922
  {
12906
- return RSTRING_PTR(value())[index];
12923
+ return RSTRING_PTR(this->value())[index];
12907
12924
  }
12908
12925
 
12909
12926
  inline char const* String::c_str() const
12910
12927
  {
12911
- return RSTRING_PTR(value());
12928
+ return RSTRING_PTR(this->value());
12912
12929
  }
12913
12930
 
12914
12931
  inline std::string String::str() const
12915
12932
  {
12916
- return std::string(RSTRING_PTR(value()), length());
12933
+ return std::string(RSTRING_PTR(this->value()), length());
12917
12934
  }
12918
12935
 
12919
12936
  template<typename T>
@@ -14820,7 +14837,7 @@ namespace Rice
14820
14837
  template <typename Attribute_T, typename Access_T, typename...Arg_Ts>
14821
14838
  inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, Access_T access, const Arg_Ts&...args)
14822
14839
  {
14823
- VALUE singleton = detail::protect(rb_singleton_class, this->value());
14840
+ VALUE singleton = detail::protect(rb_singleton_class, this->validated_value());
14824
14841
  return this->define_attr_internal<Attribute_T, Access_T>(singleton, name, std::forward<Attribute_T>(attribute), access, args...);
14825
14842
  }
14826
14843
 
data/lib/rice/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rice
2
- VERSION = "4.11.0"
2
+ VERSION = "4.11.1"
3
3
  end
data/rice/Data_Type.ipp CHANGED
@@ -368,7 +368,7 @@ namespace Rice
368
368
  template <typename Attribute_T, typename Access_T, typename...Arg_Ts>
369
369
  inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, Access_T access, const Arg_Ts&...args)
370
370
  {
371
- VALUE singleton = detail::protect(rb_singleton_class, this->value());
371
+ VALUE singleton = detail::protect(rb_singleton_class, this->validated_value());
372
372
  return this->define_attr_internal<Attribute_T, Access_T>(singleton, name, std::forward<Attribute_T>(attribute), access, args...);
373
373
  }
374
374
 
@@ -37,6 +37,12 @@ namespace Rice
37
37
  Object(Object&& other) = default;
38
38
  Object& operator=(Object&& other) = default;
39
39
 
40
+ //! Implicit conversion to VALUE.
41
+ operator VALUE() const;
42
+
43
+ //! Explicitly get the encapsulated VALUE.
44
+ VALUE value() const;
45
+
40
46
  //! Returns false if the object is nil or false; returns true
41
47
  //! otherwise.
42
48
  explicit operator bool() const;
@@ -44,11 +50,6 @@ namespace Rice
44
50
  //! Returns true if the object is nil, false otherwise.
45
51
  bool is_nil() const;
46
52
 
47
- //! Implicit conversion to VALUE.
48
- operator VALUE() const;
49
-
50
- //! Explicitly get the encapsulated VALUE.
51
- VALUE value() const;
52
53
 
53
54
  //! Get the class of an object.
54
55
  /*! \return the object's Class.
@@ -249,6 +250,10 @@ namespace Rice
249
250
  void remove_const(Identifier name);
250
251
 
251
252
  protected:
253
+ //! Checks the encapsulated VALUE is not nil and returns it. If it is nil
254
+ //! an exception is thrown.
255
+ VALUE validated_value() const;
256
+
252
257
  //! Set the encapsulated value.
253
258
  void set_value(VALUE value);
254
259
 
@@ -8,16 +8,9 @@ namespace Rice
8
8
  {
9
9
  }
10
10
 
11
- inline Object::operator bool() const
12
- {
13
- // Bypass getter to not raise exception
14
- return RTEST(this->value_.value());
15
- }
16
-
17
- inline bool Object::is_nil() const
11
+ inline VALUE Object::value() const
18
12
  {
19
- // Bypass getter to not raise exception
20
- return NIL_P(this->value_.value());
13
+ return this->value_.value();
21
14
  }
22
15
 
23
16
  inline Object::operator VALUE() const
@@ -25,9 +18,9 @@ namespace Rice
25
18
  return this->value();
26
19
  }
27
20
 
28
- inline VALUE Object::value() const
21
+ inline VALUE Object::validated_value() const
29
22
  {
30
- VALUE result = this->value_.value();
23
+ VALUE result = this->value();
31
24
 
32
25
  if (result == Qnil)
33
26
  {
@@ -38,6 +31,16 @@ namespace Rice
38
31
  return result;
39
32
  }
40
33
 
34
+ inline Object::operator bool() const
35
+ {
36
+ return RTEST(this->value());
37
+ }
38
+
39
+ inline bool Object::is_nil() const
40
+ {
41
+ return NIL_P(this->value());
42
+ }
43
+
41
44
  template<typename ...Parameter_Ts>
42
45
  inline Object Object::call(Identifier id, Parameter_Ts... args) const
43
46
  {
@@ -49,7 +52,7 @@ namespace Rice
49
52
  easy to duplicate by setting GC.stress to true and calling a constructor
50
53
  that takes multiple values like a std::pair wrapper. */
51
54
  std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(std::forward<Parameter_Ts>(args))... };
52
- return detail::protect(rb_funcallv, value(), id.id(), (int)values.size(), (const VALUE*)values.data());
55
+ return detail::protect(rb_funcallv, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data());
53
56
  }
54
57
 
55
58
  template<typename ...Parameter_Ts>
@@ -57,13 +60,13 @@ namespace Rice
57
60
  {
58
61
  /* IMPORTANT - See call() above */
59
62
  std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(args)... };
60
- return detail::protect(rb_funcallv_kw, value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
63
+ return detail::protect(rb_funcallv_kw, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
61
64
  }
62
65
 
63
66
  template<typename T>
64
67
  inline void Object::iv_set(Identifier name, T const& value)
65
68
  {
66
- detail::protect(rb_ivar_set, this->value(), name.id(), detail::To_Ruby<T>().convert(value));
69
+ detail::protect(rb_ivar_set, this->validated_value(), name.id(), detail::To_Ruby<T>().convert(value));
67
70
  }
68
71
 
69
72
  inline int Object::compare(Object const& other) const
@@ -79,66 +82,71 @@ namespace Rice
79
82
  return this->is_nil() && other.is_nil();
80
83
  }
81
84
 
82
- VALUE result = detail::protect(rb_equal, this->value(), other.value());
85
+ VALUE result = detail::protect(rb_equal, this->validated_value(), other.validated_value());
83
86
  return RB_TEST(result);
84
87
  }
85
88
 
86
89
  inline bool Object::is_eql(const Object& other) const
87
90
  {
88
- VALUE result = detail::protect(rb_eql, this->value(), other.value());
91
+ if (this->is_nil() || other.is_nil())
92
+ {
93
+ return this->is_nil() && other.is_nil();
94
+ }
95
+
96
+ VALUE result = detail::protect(rb_eql, this->validated_value(), other.validated_value());
89
97
  return RB_TEST(result);
90
98
  }
91
99
 
92
100
  inline void Object::freeze()
93
101
  {
94
- detail::protect(rb_obj_freeze, value());
102
+ detail::protect(rb_obj_freeze, this->validated_value());
95
103
  }
96
104
 
97
105
  inline bool Object::is_frozen() const
98
106
  {
99
- return RB_OBJ_FROZEN(value());
107
+ return RB_OBJ_FROZEN(this->validated_value());
100
108
  }
101
109
 
102
110
  inline int Object::rb_type() const
103
111
  {
104
- return ::rb_type(this->value());
112
+ return ::rb_type(this->validated_value());
105
113
  }
106
114
 
107
115
  inline VALUE Object::object_id() const
108
116
  {
109
- return detail::protect(rb_obj_id, this->value());
117
+ return detail::protect(rb_obj_id, this->validated_value());
110
118
  }
111
119
 
112
120
  inline bool Object::is_a(Object klass) const
113
121
  {
114
- VALUE result = detail::protect(rb_obj_is_kind_of, this->value(), klass.value());
122
+ VALUE result = detail::protect(rb_obj_is_kind_of, this->validated_value(), klass.validated_value());
115
123
  return RB_TEST(result);
116
124
  }
117
125
 
118
126
  inline void Object::extend(Module const& mod)
119
127
  {
120
- detail::protect(rb_extend_object, this->value(), mod.value());
128
+ detail::protect(rb_extend_object, this->validated_value(), mod.validated_value());
121
129
  }
122
130
 
123
131
  inline bool Object::respond_to(Identifier id) const
124
132
  {
125
- return bool(rb_respond_to(this->value(), id.id()));
133
+ return bool(rb_respond_to(this->validated_value(), id.id()));
126
134
  }
127
135
 
128
136
  inline bool Object::is_instance_of(Object klass) const
129
137
  {
130
- VALUE result = detail::protect(rb_obj_is_instance_of, this->value(), klass.value());
138
+ VALUE result = detail::protect(rb_obj_is_instance_of, this->validated_value(), klass.validated_value());
131
139
  return RB_TEST(result);
132
140
  }
133
141
 
134
142
  inline Object Object::iv_get(Identifier name) const
135
143
  {
136
- return detail::protect(rb_ivar_get, this->value(), name.id());
144
+ return detail::protect(rb_ivar_get, this->validated_value(), name.id());
137
145
  }
138
146
 
139
147
  inline Object Object::attr_get(Identifier name) const
140
148
  {
141
- return detail::protect(rb_attr_get, this->value(), name.id());
149
+ return detail::protect(rb_attr_get, this->validated_value(), name.id());
142
150
  }
143
151
 
144
152
  inline void Object::set_value(VALUE value)
@@ -148,20 +156,20 @@ namespace Rice
148
156
 
149
157
  inline Object Object::const_get(Identifier name) const
150
158
  {
151
- return detail::protect(rb_const_get, this->value(), name.id());
159
+ return detail::protect(rb_const_get, this->validated_value(), name.id());
152
160
  }
153
161
 
154
162
  inline bool Object::const_defined(Identifier name) const
155
163
  {
156
- size_t result = detail::protect(rb_const_defined, this->value(), name.id());
164
+ size_t result = detail::protect(rb_const_defined, this->validated_value(), name.id());
157
165
  return bool(result);
158
166
  }
159
167
 
160
168
  inline Object Object::const_set(Identifier name, Object value)
161
169
  {
162
170
  // We will allow setting constants to Qnil, or the decimal value of 4. This happens
163
- // in C++ libraries with enums. Thus skip the value() method that raises excptions
164
- detail::protect(rb_const_set, this->value(), name.id(), value.value_.value());
171
+ // in C++ libraries with enums. Thus use value() instead of validated_value
172
+ detail::protect(rb_const_set, this->validated_value(), name.id(), value.value());
165
173
  return value;
166
174
  }
167
175
 
@@ -176,7 +184,7 @@ namespace Rice
176
184
 
177
185
  inline void Object::remove_const(Identifier name)
178
186
  {
179
- detail::protect(rb_mod_remove_const, this->value(), name.to_sym());
187
+ detail::protect(rb_mod_remove_const, this->validated_value(), name.to_sym());
180
188
  }
181
189
 
182
190
  inline bool operator==(Object const& lhs, Object const& rhs)
@@ -47,22 +47,22 @@ namespace Rice
47
47
 
48
48
  inline size_t String::length() const
49
49
  {
50
- return RSTRING_LEN(value());
50
+ return RSTRING_LEN(this->value());
51
51
  }
52
52
 
53
53
  inline char String::operator[](ptrdiff_t index) const
54
54
  {
55
- return RSTRING_PTR(value())[index];
55
+ return RSTRING_PTR(this->value())[index];
56
56
  }
57
57
 
58
58
  inline char const* String::c_str() const
59
59
  {
60
- return RSTRING_PTR(value());
60
+ return RSTRING_PTR(this->value());
61
61
  }
62
62
 
63
63
  inline std::string String::str() const
64
64
  {
65
- return std::string(RSTRING_PTR(value()), length());
65
+ return std::string(RSTRING_PTR(this->value()), length());
66
66
  }
67
67
 
68
68
  template<typename T>
@@ -9,7 +9,7 @@
9
9
  */
10
10
  inline auto& include_module(Module const& inc)
11
11
  {
12
- detail::protect(rb_include_module, this->value(), inc.value());
12
+ detail::protect(rb_include_module, this->validated_value(), inc.value());
13
13
  return *this;
14
14
  }
15
15
 
@@ -33,7 +33,7 @@ inline auto& include_module(Module const& inc)
33
33
  template<typename Method_T, typename...Arg_Ts>
34
34
  inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...args)
35
35
  {
36
- this->wrap_native_method(this->value(), name, std::forward<Method_T>(method), args...);
36
+ this->wrap_native_method(this->validated_value(), name, std::forward<Method_T>(method), args...);
37
37
  return *this;
38
38
  }
39
39
 
@@ -51,7 +51,7 @@ inline auto& define_method(std::string name, Method_T&& method, const Arg_Ts&...
51
51
  template<typename Function_T, typename...Arg_Ts>
52
52
  inline auto& define_function(std::string name, Function_T&& func, const Arg_Ts&...args)
53
53
  {
54
- this->wrap_native_function(this->value(), name, std::forward<Function_T>(func), args...);
54
+ this->wrap_native_function(this->validated_value(), name, std::forward<Function_T>(func), args...);
55
55
  return *this;
56
56
  }
57
57
 
@@ -125,6 +125,6 @@ template<typename Constant_T>
125
125
  inline auto& define_constant(std::string name, Constant_T value)
126
126
  {
127
127
  using Base_T = detail::remove_cv_recursive_t<Constant_T>;
128
- detail::protect(rb_define_const, this->value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
128
+ detail::protect(rb_define_const, this->validated_value(), name.c_str(), detail::To_Ruby<Base_T>().convert(value));
129
129
  return *this;
130
130
  }
@@ -165,6 +165,10 @@ namespace Rice::detail
165
165
  T defaultValue = this->arg()->template defaultValue<T>();
166
166
  return this->toRuby_.convert(defaultValue);
167
167
  }
168
+ else
169
+ {
170
+ throw std::runtime_error("Default value not allowed for parameter " + this->arg()->name);
171
+ }
168
172
  }
169
173
  else
170
174
  {
data/test/test_Object.cpp CHANGED
@@ -97,12 +97,7 @@ TESTCASE(implicit_conversion_to_value)
97
97
  ASSERT_EQUAL(INT2NUM(42), (VALUE)Object(INT2NUM(42)));
98
98
  ASSERT_EQUAL(Qfalse, (VALUE)Object(Qfalse));
99
99
  ASSERT_EQUAL(Qundef, (VALUE)Object(Qundef));
100
-
101
- ASSERT_EXCEPTION_CHECK(
102
- std::runtime_error,
103
- (VALUE)Object(Qnil),
104
- ASSERT_EQUAL("Rice Object does not wrap a Ruby object", ex.what())
105
- );
100
+ ASSERT_EQUAL(Qnil, (VALUE)Object(Qnil));
106
101
  }
107
102
 
108
103
  TESTCASE(explicit_conversion_to_value)
@@ -111,12 +106,7 @@ TESTCASE(explicit_conversion_to_value)
111
106
  ASSERT_EQUAL(INT2NUM(42), Object(INT2NUM(42)).value());
112
107
  ASSERT_EQUAL(Qfalse, Object(Qfalse).value());
113
108
  ASSERT_EQUAL(Qundef, Object(Qundef).value());
114
-
115
- ASSERT_EXCEPTION_CHECK(
116
- std::runtime_error,
117
- Object(Qnil).value(),
118
- ASSERT_EQUAL("Rice Object does not wrap a Ruby object", ex.what())
119
- );
109
+ ASSERT_EQUAL(Qnil, Object(Qnil).value());
120
110
  }
121
111
 
122
112
  TESTCASE(class_of)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rice
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.0
4
+ version: 4.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Brannan