rucy 0.3.12 → 0.3.13
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 +4 -4
- data/.github/workflows/release-gem.yml +2 -16
- data/ChangeLog.md +6 -0
- data/README.md +140 -9
- data/VERSION +1 -1
- data/rucy.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e00e91444fff75c3bcce95970122b74ed7b90cfd25fa624c39135e9edd25bc94
|
|
4
|
+
data.tar.gz: f97ce5707abc53840eb150f0d04914cf017ee806bb9561e4310647c2f933b3ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5309d718c81ea92139084d38894b099fb511f9fae0e9da1387740046136e1da8cc054a8ebadbc1353e430ec738264c5bba92c7e9f51ea9f9b7b8701a5b25be3
|
|
7
|
+
data.tar.gz: fcfd31e82f5c3abb5e13bcf827540fb87a5e32dcafad5f77d4fea15e0285658b6ccd2db2e0170c828e65f1480975c05390b63d93515bc0260f0266acaf892f82
|
|
@@ -36,23 +36,9 @@ jobs:
|
|
|
36
36
|
echo path=$(ruby -e 'print Dir.glob("*.gem").first') >> $GITHUB_OUTPUT
|
|
37
37
|
|
|
38
38
|
- name: create github release
|
|
39
|
-
id: release
|
|
40
|
-
uses: actions/create-release@v1
|
|
41
39
|
env:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
tag_name: ${{ github.ref }}
|
|
45
|
-
release_name: ${{ github.ref }}
|
|
46
|
-
|
|
47
|
-
- name: upload to github release
|
|
48
|
-
uses: actions/upload-release-asset@v1
|
|
49
|
-
env:
|
|
50
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
51
|
-
with:
|
|
52
|
-
upload_url: ${{ steps.release.outputs.upload_url }}
|
|
53
|
-
asset_path: ./${{ steps.gem.outputs.path }}
|
|
54
|
-
asset_name: ${{ steps.gem.outputs.path }}
|
|
55
|
-
asset_content_type: application/zip
|
|
40
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
41
|
+
run: ruby -I.github/workflows -rutils -e 'release(*ARGV)' ./${{ steps.gem.outputs.path }}
|
|
56
42
|
|
|
57
43
|
- name: upload to rubygems
|
|
58
44
|
env:
|
data/ChangeLog.md
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Rucy - A Ruby C++
|
|
1
|
+
# Rucy - A Ruby C++ extension helper library
|
|
2
2
|
|
|
3
3
|
[](https://deepwiki.com/xord/rucy)
|
|
4
4
|

|
|
@@ -21,19 +21,27 @@ Thanks for your support! 🙌
|
|
|
21
21
|
|
|
22
22
|
## 🚀 About
|
|
23
23
|
|
|
24
|
-
**Rucy**
|
|
24
|
+
**Rucy** is a thin C++ layer on top of Ruby's C API. It reduces the boilerplate involved in writing a Ruby extension in C++ by wrapping `VALUE`, providing exception-safe method definitions, and converting between native types and Ruby values.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
It is used by the native extensions in the `xord/*` family — [Beeps](https://github.com/xord/beeps), [Rays](https://github.com/xord/rays), and [Reflex](https://github.com/xord/reflex). It depends on [Xot](https://github.com/xord/xot) for low-level utilities such as reference counting, the pimpl idiom, and the string / exception classes.
|
|
27
|
+
|
|
28
|
+
Like Xot, Rucy exists primarily for our own gems. The API is stable enough for us to build on, but it is not a general-purpose extension framework — feel free to read it and learn from it, but pin a specific version if you depend on it directly.
|
|
29
|
+
|
|
30
|
+
## 📋 Requirements
|
|
31
|
+
|
|
32
|
+
- Ruby **3.0.0** or later
|
|
33
|
+
- A C++ compiler with C++20 support
|
|
34
|
+
- [Xot](https://rubygems.org/gems/xot) (declared as a runtime dependency)
|
|
35
|
+
- Rake and test-unit (development only)
|
|
28
36
|
|
|
29
37
|
## 📦 Installation
|
|
30
38
|
|
|
31
39
|
Add this line to your Gemfile:
|
|
32
40
|
```ruby
|
|
33
|
-
|
|
41
|
+
gem 'rucy'
|
|
34
42
|
```
|
|
35
43
|
|
|
36
|
-
Then
|
|
44
|
+
Then install:
|
|
37
45
|
```bash
|
|
38
46
|
$ bundle install
|
|
39
47
|
```
|
|
@@ -43,11 +51,134 @@ Or install it directly:
|
|
|
43
51
|
$ gem install rucy
|
|
44
52
|
```
|
|
45
53
|
|
|
46
|
-
|
|
54
|
+
When linking against Rucy from your own extension, point `extconf.rb` at the gem's `include/` and `lib/` directories — `Rucy::Extension.inc_dir` and `Rucy::Extension.lib_dir` return the right paths.
|
|
55
|
+
|
|
56
|
+
## 📚 What's Included
|
|
57
|
+
|
|
58
|
+
### C++ headers (`include/rucy/`)
|
|
59
|
+
|
|
60
|
+
| Header | Provides |
|
|
61
|
+
| ------------- | ---------------------------------------------------------------------------------------- |
|
|
62
|
+
| `rucy.h` | `Rucy::init()`, the `Rucy` module, and the error class hierarchy |
|
|
63
|
+
| `ruby.h` | A safe `<ruby.h>` wrapper plus the `RubyValue` / `RubySymbol` typedefs |
|
|
64
|
+
| `value.h` | `Rucy::Value` — wraps `VALUE` with type predicates, conversions, and method calls |
|
|
65
|
+
| `module.h` | `Rucy::Module` — `define_module`, `define_class`, `define_method`, ... |
|
|
66
|
+
| `class.h` | `Rucy::Class` — adds `define_alloc_func` on top of `Module` |
|
|
67
|
+
| `function.h` | `Rucy::call("method", ...)`, `eval`, `protect` — invoke Ruby code with C++ exception safety |
|
|
68
|
+
| `symbol.h` | `Rucy::Symbol` plus the `RUCY_SYM`, `RUCY_SYM_Q`, `RUCY_SYM_B` macros |
|
|
69
|
+
| `exception.h` | `RubyException`, `RubyJumpTag`, and `raise` / `*_error` throw helpers |
|
|
70
|
+
| `extension.h` | Method definition macros (`RUCY_DEF0` ... `RUCY_DEFN`) and `VALUE` ↔ native converters |
|
|
71
|
+
|
|
72
|
+
### Method definition macros
|
|
73
|
+
|
|
74
|
+
| Macro | Purpose |
|
|
75
|
+
| ---------------------------- | ----------------------------------------------------------------------- |
|
|
76
|
+
| `RUCY_DEF0` ... `RUCY_DEF12` | Define a Ruby method that takes 0–12 arguments |
|
|
77
|
+
| `RUCY_DEFN` | Define a variadic Ruby method (`int argc, const Value* argv`) |
|
|
78
|
+
| `RUCY_DEF_ALLOC` | Define an allocator function for a class |
|
|
79
|
+
| `RUCY_DEF_END` | Close a method definition; converts C++ exceptions into Ruby exceptions |
|
|
80
|
+
| `RUCY_TRY` / `RUCY_CATCH` | Wrap any block of C++ code in Ruby-safe exception translation |
|
|
81
|
+
|
|
82
|
+
### Type conversion macros
|
|
83
|
+
|
|
84
|
+
`RUCY_DECLARE_VALUE_FROM_TO` / `RUCY_DEFINE_VALUE_FROM_TO` (and the `WRAPPER` / `ARRAY` variants) generate `Rucy::value(...)` and `Rucy::value_to<T>(...)` overloads so you can move data between Ruby and a native class with one line of declaration plus one line of definition.
|
|
85
|
+
|
|
86
|
+
### Ruby side (`lib/rucy/`)
|
|
87
|
+
|
|
88
|
+
| Module | Purpose |
|
|
89
|
+
| ----------------- | ----------------------------------------------------------------------------------------------- |
|
|
90
|
+
| `Rucy::Extension` | Path / name / version helpers, mirroring `Xot::Extension` for Rucy-based gems |
|
|
91
|
+
| `Rucy::Rake` | Rake DSL extensions used by `xord/*` gems (`build_native_library`, `build_ruby_extension`, ...) |
|
|
92
|
+
|
|
93
|
+
### Tools (`bin/`)
|
|
94
|
+
|
|
95
|
+
| Tool | Purpose |
|
|
96
|
+
| ----------- | ------------------------------------------------------------------------------------- |
|
|
97
|
+
| `rucy2rdoc` | Extract doc comments from C++ files using `RUCY_DEF*` macros into RDoc-friendly stubs |
|
|
98
|
+
|
|
99
|
+
## 💡 Usage
|
|
100
|
+
|
|
101
|
+
### A minimal extension
|
|
102
|
+
|
|
103
|
+
```cpp
|
|
104
|
+
// ext/hello/hello.cpp
|
|
105
|
+
#include <rucy/rucy.h>
|
|
106
|
+
#include <rucy/extension.h>
|
|
107
|
+
|
|
108
|
+
using namespace Rucy;
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
Returns a friendly greeting.
|
|
112
|
+
*/
|
|
113
|
+
RUCY_DEF1(greet, name)
|
|
114
|
+
{
|
|
115
|
+
return value(Xot::String("hello, ") + name.c_str());
|
|
116
|
+
}
|
|
117
|
+
RUCY_DEF_END
|
|
118
|
+
|
|
119
|
+
extern "C" void
|
|
120
|
+
Init_hello ()
|
|
121
|
+
{
|
|
122
|
+
RUCY_TRY
|
|
123
|
+
|
|
124
|
+
Module mHello = define_module("Hello");
|
|
125
|
+
mHello.define_module_function("greet", greet);
|
|
126
|
+
|
|
127
|
+
RUCY_CATCH
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
# ext/hello/extconf.rb
|
|
133
|
+
require 'rucy/extension'
|
|
134
|
+
require 'mkmf'
|
|
135
|
+
|
|
136
|
+
$INCFLAGS << " -I#{Xot::Extension.inc_dir} -I#{Rucy::Extension.inc_dir}"
|
|
137
|
+
$LDFLAGS << " -L#{Xot::Extension.lib_dir} -L#{Rucy::Extension.lib_dir} -lxot -lrucy"
|
|
138
|
+
|
|
139
|
+
create_makefile 'hello/hello'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
# Use it from Ruby
|
|
144
|
+
require 'hello/hello'
|
|
145
|
+
Hello.greet 'world' # => "hello, world"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Exception-safe method bodies
|
|
47
149
|
|
|
48
|
-
|
|
150
|
+
Anything you throw inside a `RUCY_DEF*` body — `Rucy::RubyException`, `std::exception`, `Xot::XotError`, or even a `const char*` — is caught by `RUCY_DEF_END` and re-raised as the corresponding Ruby exception. You can also raise directly:
|
|
151
|
+
|
|
152
|
+
```cpp
|
|
153
|
+
RUCY_DEF1(divide, n)
|
|
154
|
+
{
|
|
155
|
+
if (n.as_i() == 0)
|
|
156
|
+
argument_error(__FILE__, __LINE__, "divide by zero");
|
|
157
|
+
return value(100 / n.as_i());
|
|
158
|
+
}
|
|
159
|
+
RUCY_DEF_END
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Calling Ruby from C++
|
|
163
|
+
|
|
164
|
+
```cpp
|
|
165
|
+
Value ary = eval("[1, 2, 3]");
|
|
166
|
+
Value n = ary.call("sum"); // => Value(6)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
For more examples, see `ext/rucy/tester.cpp` (used by the test suite) and the native extensions in [Beeps](https://github.com/xord/beeps), [Rays](https://github.com/xord/rays), and [Reflex](https://github.com/xord/reflex).
|
|
170
|
+
|
|
171
|
+
## 🛠️ Development
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
$ rake lib # build the native C++ library (librucy)
|
|
175
|
+
$ rake ext # build the test extension
|
|
176
|
+
$ rake test # run the test suite
|
|
177
|
+
$ rake doc # generate RDoc from C++ sources via rucy2rdoc
|
|
178
|
+
$ rake # default: builds the extension
|
|
179
|
+
```
|
|
49
180
|
|
|
50
|
-
|
|
181
|
+
Several headers and sources are ERB templates (`*.erb`) expanded automatically at build time. `NPARAM_MAX = 12` in the Rakefile auto-generates `RUCY_DEF0` ... `RUCY_DEF12` and the matching overloads of `call`, `protect`, and friends.
|
|
51
182
|
|
|
52
183
|
## 📜 License
|
|
53
184
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.13
|
data/rucy.gemspec
CHANGED
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
|
27
27
|
|
|
28
|
-
s.add_dependency 'xot', '~> 0.3.
|
|
28
|
+
s.add_dependency 'xot', '~> 0.3.13'
|
|
29
29
|
|
|
30
30
|
s.files = `git ls-files`.split $/
|
|
31
31
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rucy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- xordog
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: xot
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.3.
|
|
19
|
+
version: 0.3.13
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.3.
|
|
26
|
+
version: 0.3.13
|
|
27
27
|
description: This library helps you to develop Ruby Extension by C++.
|
|
28
28
|
email: xordog@gmail.com
|
|
29
29
|
executables:
|