m2m_keygen 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/Gemfile.lock +1 -1
- data/README.md +87 -4
- data/docs/M2mKeygen/Error.html +1 -1
- data/docs/M2mKeygen/ParamsEncoder.html +321 -0
- data/docs/M2mKeygen/Signature.html +680 -0
- data/docs/M2mKeygen/Types.html +147 -0
- data/docs/M2mKeygen.html +7 -5
- data/docs/_index.html +46 -1
- data/docs/class_list.html +1 -1
- data/docs/file.README.html +94 -5
- data/docs/index.html +94 -5
- data/docs/method_list.html +56 -0
- data/docs/top-level-namespace.html +1 -1
- data/lib/m2m_keygen/params_encoder.rb +56 -0
- data/lib/m2m_keygen/signature.rb +78 -0
- data/lib/m2m_keygen/types/params_type.rb +25 -0
- data/lib/m2m_keygen/version.rb +1 -1
- data/lib/m2m_keygen.rb +5 -2
- data/sorbet/rbi/gems/{rb-fsevent@0.11.1.rbi → rb-fsevent@0.11.2.rbi} +0 -0
- data/sorbet/rbi/gems/zeitwerk@2.6.0.rbi +861 -2
- data/sorbet/rbi/manual.rbi +7 -0
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e37329faa3536c931f8a622280c9c23f366135729263c749a6965c4a80ed9c4
|
4
|
+
data.tar.gz: dc593bf4e794ffcd877262f851303c8b4b9f69fbd33befd43fd7a3fb847a59c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1099d8210b5b866851ea0e80b1c6093231c5d3ce6173a507e2a0982d3113483e395db5148053daa94d3e3e73fa7ddd29f9567f2b670eee88dd36fc24a5ce4f4
|
7
|
+
data.tar.gz: 10b715091a58bfd03b5cb8b8ccb812c3f35fc747a2e3bdd029624577ac80cfa8468b36d5cf57f9b88464459ea808d65548d9e29e3ffff30b7b5fc07a8eca3afd
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.3.0]
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Signature class for basic functionality for the gem.
|
15
|
+
- ParamsEncoder class for formating params
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Comprehensive README
|
20
|
+
- Added various minimal require
|
21
|
+
|
10
22
|
## [0.2.1]
|
11
23
|
|
12
24
|
### Added
|
@@ -19,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
19
31
|
|
20
32
|
- Basic skeleton for gem
|
21
33
|
|
22
|
-
[unreleased]: https://github.com/Billcorporate/m2m_keygen_ruby/compare/v0.
|
34
|
+
[unreleased]: https://github.com/Billcorporate/m2m_keygen_ruby/compare/v0.3.0...HEAD
|
35
|
+
[0.3.0]: https://github.com/Billcorporate/m2m_keygen_ruby/releases/tag/v0.3.0
|
23
36
|
[0.2.1]: https://github.com/Billcorporate/m2m_keygen_ruby/releases/tag/v0.2.1
|
24
37
|
[0.2.0]: https://github.com/Billcorporate/m2m_keygen_ruby/releases/tag/v0.2.0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# M2mKeygen
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
This gem exists for simplifying Machine to Machine signature generation and verification in a secure way.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -16,7 +14,82 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
16
14
|
|
17
15
|
## Usage
|
18
16
|
|
19
|
-
|
17
|
+
### Signature
|
18
|
+
|
19
|
+
This gem provides a module for signing and checking signature for HTTP requests
|
20
|
+
|
21
|
+
#### Initialization
|
22
|
+
|
23
|
+
You should initialize the `Signature` once (in an initializer for example) with your secret key and eventually an encryption algorithm.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
AuthSignature = M2mKeygen::Signature.new("my_secret_key", algorithm: "sha256")
|
27
|
+
|
28
|
+
AuthSignature = M2mKeygen::Signature.new("my_secret_key") # => Will default algorithm to sha512
|
29
|
+
```
|
30
|
+
|
31
|
+
#### Signing
|
32
|
+
|
33
|
+
Use the `sign` method to generate a new signature.
|
34
|
+
|
35
|
+
- `params` is a params hash as used in Rack. The order of keys isn't important as the gem will reformat them.
|
36
|
+
- `verb` is the http verb
|
37
|
+
- `path` is the path for the request
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
AuthSignature.sign(
|
41
|
+
params: {
|
42
|
+
"a" => "test",
|
43
|
+
:b => 1,
|
44
|
+
"d" => %w[a b],
|
45
|
+
"c" => {
|
46
|
+
"e" => 45
|
47
|
+
}
|
48
|
+
},
|
49
|
+
verb: "get",
|
50
|
+
path: "/path"
|
51
|
+
) # => "a52168521868ebb37a38f90ec943163d9acb6ceb982206f437e1feb9ca32e7c1a8edef68f0ff4e195aeca1da93ae9afc8da214cb51a812fc6cc3730fdc7613fa"
|
52
|
+
```
|
53
|
+
|
54
|
+
After generating the signature send it alongside your request for verification on the receiver side.
|
55
|
+
|
56
|
+
#### Verifying
|
57
|
+
|
58
|
+
Use the `validate` method to verify that a received signature correspond to the HTTP request.
|
59
|
+
|
60
|
+
- `params` is a params hash as used in Rack. The order of keys isn't important as the gem will reformat them.
|
61
|
+
- `verb` is the http verb
|
62
|
+
- `path` is the path for the request
|
63
|
+
- `signature` is the received signature
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
AuthSignature.validate(
|
67
|
+
params: {
|
68
|
+
"a" => "test",
|
69
|
+
:b => 1,
|
70
|
+
"d" => %w[a b],
|
71
|
+
"c" => {
|
72
|
+
"e" => 45
|
73
|
+
}
|
74
|
+
},
|
75
|
+
verb: "get",
|
76
|
+
path: "/path",
|
77
|
+
signature:
|
78
|
+
"a52168521868ebb37a38f90ec943163d9acb6ceb982206f437e1feb9ca32e7c1a8edef68f0ff4e195aeca1da93ae9afc8da214cb51a812fc6cc3730fdc7613fa"
|
79
|
+
) #=> true
|
80
|
+
```
|
81
|
+
|
82
|
+
If the validation is true, the request was signed with the same algorithm and same secret key.
|
83
|
+
|
84
|
+
## How does it works
|
85
|
+
|
86
|
+
This is intended for a secure discussion between 2 servers and not something in a browser as the secret key must be stored and used both side (and you don't want to send the secret key in the browser).
|
87
|
+
|
88
|
+
Both server will have the same secret key.
|
89
|
+
The sender will generate a signature matching the HTTP request it will be sending and add it to the request in a designated header.
|
90
|
+
The receiver will generate the same signature from the HTTP request it has received and will compare it with the signature in the header.
|
91
|
+
|
92
|
+
The comparison will be done in constant time (i.e. secure) because both string will be hexdigest from a HMAC with the same algorithm.
|
20
93
|
|
21
94
|
## Development
|
22
95
|
|
@@ -24,6 +97,16 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
24
97
|
|
25
98
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
26
99
|
|
100
|
+
Every commit/push is checked by overcommit. You should (must) activate overcommit by using `overcommit -i` post installation.
|
101
|
+
|
102
|
+
Tool used in dev:
|
103
|
+
|
104
|
+
- Rubocop
|
105
|
+
- Prettier
|
106
|
+
- Yard
|
107
|
+
- Sorbet
|
108
|
+
- RSpec
|
109
|
+
|
27
110
|
## Contributing
|
28
111
|
|
29
112
|
Bug reports and pull requests are welcome on GitHub at https://github.com/zaratan/m2m_keygen. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/zaratan/m2m_keygen/blob/main/CODE_OF_CONDUCT.md).
|
data/docs/M2mKeygen/Error.html
CHANGED
@@ -125,7 +125,7 @@
|
|
125
125
|
</div>
|
126
126
|
|
127
127
|
<div id="footer">
|
128
|
-
Generated on
|
128
|
+
Generated on Tue Aug 30 11:26:10 2022 by
|
129
129
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
130
130
|
0.9.28 (ruby-3.1.2).
|
131
131
|
</div>
|
@@ -0,0 +1,321 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
Class: M2mKeygen::ParamsEncoder
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.28
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="../css/style.css" type="text/css" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="../css/common.css" type="text/css" />
|
16
|
+
|
17
|
+
<script type="text/javascript">
|
18
|
+
pathId = "M2mKeygen::ParamsEncoder";
|
19
|
+
relpath = '../';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="../class_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="../_index.html">Index (P)</a> »
|
40
|
+
<span class='title'><span class='object_link'><a href="../M2mKeygen.html" title="M2mKeygen (module)">M2mKeygen</a></span></span>
|
41
|
+
»
|
42
|
+
<span class="title">ParamsEncoder</span>
|
43
|
+
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div id="search">
|
47
|
+
|
48
|
+
<a class="full_list_link" id="class_list_link"
|
49
|
+
href="../class_list.html">
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
56
|
+
</a>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div id="content"><h1>Class: M2mKeygen::ParamsEncoder
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
</h1>
|
67
|
+
<div class="box_info">
|
68
|
+
|
69
|
+
<dl>
|
70
|
+
<dt>Inherits:</dt>
|
71
|
+
<dd>
|
72
|
+
<span class="inheritName">Object</span>
|
73
|
+
|
74
|
+
<ul class="fullTree">
|
75
|
+
<li>Object</li>
|
76
|
+
|
77
|
+
<li class="next">M2mKeygen::ParamsEncoder</li>
|
78
|
+
|
79
|
+
</ul>
|
80
|
+
<a href="#" class="inheritanceTree">show all</a>
|
81
|
+
|
82
|
+
</dd>
|
83
|
+
</dl>
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
<dl>
|
89
|
+
<dt>Extended by:</dt>
|
90
|
+
<dd>T::Sig</dd>
|
91
|
+
</dl>
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
<dl>
|
101
|
+
<dt>Defined in:</dt>
|
102
|
+
<dd>lib/m2m_keygen/params_encoder.rb</dd>
|
103
|
+
</dl>
|
104
|
+
|
105
|
+
</div>
|
106
|
+
|
107
|
+
<h2>Overview</h2><div class="docstring">
|
108
|
+
<div class="discussion">
|
109
|
+
|
110
|
+
<p>Encoder for params hash</p>
|
111
|
+
|
112
|
+
|
113
|
+
</div>
|
114
|
+
</div>
|
115
|
+
<div class="tags">
|
116
|
+
|
117
|
+
|
118
|
+
</div>
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
<h2>
|
127
|
+
Instance Method Summary
|
128
|
+
<small><a href="#" class="summary_toggle">collapse</a></small>
|
129
|
+
</h2>
|
130
|
+
|
131
|
+
<ul class="summary">
|
132
|
+
|
133
|
+
<li class="public ">
|
134
|
+
<span class="summary_signature">
|
135
|
+
|
136
|
+
<a href="#encode-instance_method" title="#encode (instance method)">#<strong>encode</strong> ⇒ String </a>
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
</span>
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
<span class="summary_desc"><div class='inline'></div></span>
|
151
|
+
|
152
|
+
</li>
|
153
|
+
|
154
|
+
|
155
|
+
<li class="public ">
|
156
|
+
<span class="summary_signature">
|
157
|
+
|
158
|
+
<a href="#initialize-instance_method" title="#initialize (instance method)">#<strong>initialize</strong>(params) ⇒ void </a>
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
</span>
|
163
|
+
|
164
|
+
|
165
|
+
<span class="note title constructor">constructor</span>
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
<span class="summary_desc"><div class='inline'></div></span>
|
175
|
+
|
176
|
+
</li>
|
177
|
+
|
178
|
+
|
179
|
+
</ul>
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
<div id="constructor_details" class="method_details_list">
|
184
|
+
<h2>Constructor Details</h2>
|
185
|
+
|
186
|
+
<div class="method_details first">
|
187
|
+
<h3 class="signature first" id="initialize-instance_method">
|
188
|
+
|
189
|
+
#<strong>initialize</strong>(params) ⇒ <tt>void</tt>
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
</h3><div class="docstring">
|
196
|
+
<div class="discussion">
|
197
|
+
|
198
|
+
|
199
|
+
</div>
|
200
|
+
</div>
|
201
|
+
<div class="tags">
|
202
|
+
<p class="tag_title">Parameters:</p>
|
203
|
+
<ul class="param">
|
204
|
+
|
205
|
+
<li>
|
206
|
+
|
207
|
+
<span class='name'>params</span>
|
208
|
+
|
209
|
+
|
210
|
+
<span class='type'>(<tt><span class='object_link'><a href="Types.html#ParamsType-constant" title="M2mKeygen::Types::ParamsType (constant)">Types::ParamsType</a></span></tt>)</span>
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
</li>
|
215
|
+
|
216
|
+
</ul>
|
217
|
+
|
218
|
+
|
219
|
+
</div><table class="source_code">
|
220
|
+
<tr>
|
221
|
+
<td>
|
222
|
+
<pre class="lines">
|
223
|
+
|
224
|
+
|
225
|
+
9
|
226
|
+
10
|
227
|
+
11</pre>
|
228
|
+
</td>
|
229
|
+
<td>
|
230
|
+
<pre class="code"><span class="info file"># File 'lib/m2m_keygen/params_encoder.rb', line 9</span>
|
231
|
+
|
232
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='rparen'>)</span>
|
233
|
+
<span class='ivar'>@params</span> <span class='op'>=</span> <span class='const'>T</span><span class='period'>.</span><span class='id identifier rubyid_let'>let</span><span class='lparen'>(</span><span class='id identifier rubyid_params'>params</span><span class='comma'>,</span> <span class='const'><span class='object_link'><a href="Types.html" title="M2mKeygen::Types (module)">Types</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Types.html#ParamsType-constant" title="M2mKeygen::Types::ParamsType (constant)">ParamsType</a></span></span><span class='rparen'>)</span>
|
234
|
+
<span class='kw'>end</span></pre>
|
235
|
+
</td>
|
236
|
+
</tr>
|
237
|
+
</table>
|
238
|
+
</div>
|
239
|
+
|
240
|
+
</div>
|
241
|
+
|
242
|
+
|
243
|
+
<div id="instance_method_details" class="method_details_list">
|
244
|
+
<h2>Instance Method Details</h2>
|
245
|
+
|
246
|
+
|
247
|
+
<div class="method_details first">
|
248
|
+
<h3 class="signature first" id="encode-instance_method">
|
249
|
+
|
250
|
+
#<strong>encode</strong> ⇒ <tt>String</tt>
|
251
|
+
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
</h3><div class="docstring">
|
257
|
+
<div class="discussion">
|
258
|
+
|
259
|
+
|
260
|
+
</div>
|
261
|
+
</div>
|
262
|
+
<div class="tags">
|
263
|
+
|
264
|
+
<p class="tag_title">Returns:</p>
|
265
|
+
<ul class="return">
|
266
|
+
|
267
|
+
<li>
|
268
|
+
|
269
|
+
|
270
|
+
<span class='type'>(<tt>String</tt>)</span>
|
271
|
+
|
272
|
+
|
273
|
+
|
274
|
+
</li>
|
275
|
+
|
276
|
+
</ul>
|
277
|
+
|
278
|
+
</div><table class="source_code">
|
279
|
+
<tr>
|
280
|
+
<td>
|
281
|
+
<pre class="lines">
|
282
|
+
|
283
|
+
|
284
|
+
14
|
285
|
+
15
|
286
|
+
16
|
287
|
+
17
|
288
|
+
18
|
289
|
+
19
|
290
|
+
20
|
291
|
+
21</pre>
|
292
|
+
</td>
|
293
|
+
<td>
|
294
|
+
<pre class="code"><span class="info file"># File 'lib/m2m_keygen/params_encoder.rb', line 14</span>
|
295
|
+
|
296
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_encode'>encode</span>
|
297
|
+
<span class='kw'>return</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_end'>"</span></span> <span class='kw'>if</span> <span class='ivar'>@params</span><span class='period'>.</span><span class='id identifier rubyid_nil?'>nil?</span> <span class='op'>||</span> <span class='ivar'>@params</span><span class='period'>.</span><span class='id identifier rubyid_empty?'>empty?</span>
|
298
|
+
<span class='ivar'>@params</span>
|
299
|
+
<span class='period'>.</span><span class='id identifier rubyid_sort_by'>sort_by</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_k'>k</span><span class='comma'>,</span> <span class='id identifier rubyid__'>_</span><span class='op'>|</span> <span class='id identifier rubyid_k'>k</span><span class='period'>.</span><span class='id identifier rubyid_to_s'>to_s</span> <span class='rbrace'>}</span>
|
300
|
+
<span class='period'>.</span><span class='id identifier rubyid_reject'>reject</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid__'>_</span><span class='comma'>,</span> <span class='id identifier rubyid_v'>v</span><span class='op'>|</span> <span class='lparen'>(</span><span class='id identifier rubyid_v'>v</span><span class='period'>.</span><span class='id identifier rubyid_is_a?'>is_a?</span><span class='lparen'>(</span><span class='const'>String</span><span class='rparen'>)</span> <span class='op'>&&</span> <span class='id identifier rubyid_v'>v</span> <span class='op'>==</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span> <span class='op'>||</span> <span class='id identifier rubyid_v'>v</span><span class='period'>.</span><span class='id identifier rubyid_nil?'>nil?</span> <span class='rbrace'>}</span>
|
301
|
+
<span class='period'>.</span><span class='id identifier rubyid_map'>map</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_k'>k</span><span class='comma'>,</span> <span class='id identifier rubyid_v'>v</span><span class='op'>|</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_k'>k</span><span class='embexpr_end'>}</span><span class='tstring_content'>=</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_jsonify_value'>jsonify_value</span><span class='lparen'>(</span><span class='id identifier rubyid_encode_value'>encode_value</span><span class='lparen'>(</span><span class='const'>T</span><span class='period'>.</span><span class='id identifier rubyid_must'>must</span><span class='lparen'>(</span><span class='id identifier rubyid_v'>v</span><span class='rparen'>)</span><span class='rparen'>)</span><span class='rparen'>)</span><span class='embexpr_end'>}</span><span class='tstring_end'>"</span></span> <span class='rbrace'>}</span>
|
302
|
+
<span class='period'>.</span><span class='id identifier rubyid_join'>join</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>&</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
303
|
+
<span class='kw'>end</span></pre>
|
304
|
+
</td>
|
305
|
+
</tr>
|
306
|
+
</table>
|
307
|
+
</div>
|
308
|
+
|
309
|
+
</div>
|
310
|
+
|
311
|
+
</div>
|
312
|
+
|
313
|
+
<div id="footer">
|
314
|
+
Generated on Tue Aug 30 11:26:10 2022 by
|
315
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
316
|
+
0.9.28 (ruby-3.1.2).
|
317
|
+
</div>
|
318
|
+
|
319
|
+
</div>
|
320
|
+
</body>
|
321
|
+
</html>
|