sashite-snn 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 189a182b820d000660357679c628df3f1adf451b8fd462f4e667ba9170453a03
4
+ data.tar.gz: 17a1049e333427994c977efe5c1170fa8114685515f0ff91b9abfb4bcdbe5963
5
+ SHA512:
6
+ metadata.gz: 6843ef5ffa7f5affa4acfe88b52eb1b837112c853d0668df67f75ac3aedbe1e0f569bd52941626417cf0a66956d472bab61f7f76fedf531a36c6fe60695f0539
7
+ data.tar.gz: 8b641153ba70b214a4bf7176169d9f456a771347851ec50618777f86b2129381c3f3b6bdb4ccb98b42975651e2d6c14930e69a42bfc233b795251ac2d14fea10
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2025 Cyril Kato
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,261 @@
1
+ # Snn.rb
2
+
3
+ [![Version](https://img.shields.io/github/v/tag/sashite/snn.rb?label=Version&logo=github)](https://github.com/sashite/snn.rb/tags)
4
+ [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/sashite/snn.rb/main)
5
+ ![Ruby](https://github.com/sashite/snn.rb/actions/workflows/main.yml/badge.svg?branch=main)
6
+ [![License](https://img.shields.io/github/license/sashite/snn.rb?label=License&logo=github)](https://github.com/sashite/snn.rb/raw/main/LICENSE.md)
7
+
8
+ > **SNN** (Style Name Notation) support for the Ruby language.
9
+
10
+ ## What is SNN?
11
+
12
+ SNN (Style Name Notation) is a consistent and rule-agnostic format for identifying piece styles in abstract strategy board games. It provides unambiguous identification of piece styles by using standardized naming conventions, enabling clear distinction between different piece traditions, variants, or design approaches within multi-style gaming environments.
13
+
14
+ This gem implements the [SNN Specification v1.0.0](https://sashite.dev/documents/snn/1.0.0/), providing a Ruby interface for working with style identifiers through a clean and minimal API.
15
+
16
+ ## Installation
17
+
18
+ ```ruby
19
+ # In your Gemfile
20
+ gem "sashite-snn"
21
+ ```
22
+
23
+ Or install manually:
24
+
25
+ ```sh
26
+ gem install sashite-snn
27
+ ```
28
+
29
+ ## SNN Format
30
+
31
+ A SNN record consists of an identifier starting with an alphabetic character, followed by optional alphabetic characters and digits:
32
+
33
+ ```
34
+ <style-id>
35
+ ```
36
+
37
+ Where:
38
+ - The identifier starts with an alphabetic character (`A-Z` for uppercase, `a-z` for lowercase)
39
+ - Subsequent characters may include alphabetic characters and digits (`A-Z`, `0-9` for uppercase styles; `a-z`, `0-9` for lowercase styles)
40
+ - **Uppercase** format denotes styles belonging to the first player
41
+ - **Lowercase** format denotes styles belonging to the second player
42
+ - The entire identifier must be entirely uppercase or entirely lowercase
43
+
44
+ ## Basic Usage
45
+
46
+ ### Creating Style Objects
47
+
48
+ The primary interface is the `Sashite::Snn::Style` class, which represents a style identifier in SNN format:
49
+
50
+ ```ruby
51
+ require "sashite/snn"
52
+
53
+ # Parse a SNN string into a style object
54
+ style = Sashite::Snn::Style.parse("CHESS")
55
+ # => #<Sashite::Snn::Style:0x... @identifier="CHESS">
56
+
57
+ lowercase_style = Sashite::Snn::Style.parse("shogi")
58
+ # => #<Sashite::Snn::Style:0x... @identifier="shogi">
59
+
60
+ # Create directly with constructor
61
+ style = Sashite::Snn::Style.new("CHESS")
62
+ lowercase_style = Sashite::Snn::Style.new("makruk")
63
+
64
+ # Convenience method
65
+ style = Sashite::Snn.style("XIANGQI")
66
+ ```
67
+
68
+ ### Converting to String and Symbol
69
+
70
+ Convert a style object to different representations:
71
+
72
+ ```ruby
73
+ style = Sashite::Snn::Style.parse("CHESS")
74
+ style.to_s # => "CHESS"
75
+ style.to_sym # => :CHESS
76
+
77
+ variant_style = Sashite::Snn::Style.parse("chess960")
78
+ variant_style.to_s # => "chess960"
79
+ variant_style.to_sym # => :chess960
80
+
81
+ # Useful for hash keys and case statements
82
+ game_config = {
83
+ style.to_sym => { pieces: chess_pieces, rules: chess_rules }
84
+ }
85
+
86
+ case style.to_sym
87
+ when :CHESS then setup_chess_game
88
+ when :SHOGI then setup_shogi_game
89
+ end
90
+ ```
91
+
92
+ ### Player Association
93
+
94
+ Check which player a style belongs to:
95
+
96
+ ```ruby
97
+ first_player_style = Sashite::Snn::Style.parse("CHESS")
98
+ first_player_style.first_player? # => true
99
+ first_player_style.second_player? # => false
100
+
101
+ second_player_style = Sashite::Snn::Style.parse("shogi")
102
+ second_player_style.first_player? # => false
103
+ second_player_style.second_player? # => true
104
+ ```
105
+
106
+ ## Validation
107
+
108
+ All parsing automatically validates input according to the SNN specification:
109
+
110
+ ```ruby
111
+ # Valid SNN strings
112
+ Sashite::Snn::Style.parse("CHESS") # ✓
113
+ Sashite::Snn::Style.parse("shogi") # ✓
114
+ Sashite::Snn::Style.parse("CHESS960") # ✓
115
+ Sashite::Snn::Style.parse("makruk") # ✓
116
+
117
+ # Valid constructor calls
118
+ Sashite::Snn::Style.new("XIANGQI") # ✓
119
+ Sashite::Snn::Style.new("janggi") # ✓
120
+
121
+ # Convenience method
122
+ Sashite::Snn.style("MINISHOGI") # ✓
123
+
124
+ # Check validity
125
+ Sashite::Snn.valid?("CHESS") # => true
126
+ Sashite::Snn.valid?("Chess") # => false (mixed case)
127
+ Sashite::Snn.valid?("123") # => false (must start with letter)
128
+ Sashite::Snn.valid?("") # => false (empty string)
129
+
130
+ # Invalid SNN strings raise ArgumentError
131
+ Sashite::Snn::Style.parse("") # ✗ ArgumentError
132
+ Sashite::Snn::Style.parse("Chess") # ✗ ArgumentError (mixed case)
133
+ Sashite::Snn::Style.parse("9CHESS") # ✗ ArgumentError (starts with digit)
134
+ Sashite::Snn::Style.parse("CHESS-960") # ✗ ArgumentError (contains hyphen)
135
+ ```
136
+
137
+ ## Examples of SNN in Practice
138
+
139
+ ### Classic Game Styles
140
+
141
+ ```ruby
142
+ # International Chess
143
+ first_player = Sashite::Snn::Style.parse("CHESS") # First player uses chess pieces
144
+ second_player = Sashite::Snn::Style.parse("chess") # Second player uses chess pieces
145
+
146
+ # Cross-style game: Chess vs Shogi
147
+ first_player = Sashite::Snn::Style.parse("CHESS") # First player uses chess pieces
148
+ second_player = Sashite::Snn::Style.parse("shogi") # Second player uses shogi pieces
149
+
150
+ # Variant games
151
+ first_player = Sashite::Snn::Style.parse("CHESS960") # First player uses Chess960 variant
152
+ second_player = Sashite::Snn::Style.parse("chess960") # Second player uses Chess960 variant
153
+ ```
154
+
155
+ ### Variant Styles
156
+
157
+ ```ruby
158
+ # Chess variants
159
+ fischer_random = Sashite::Snn::Style.parse("CHESS960")
160
+ king_of_hill = Sashite::Snn::Style.parse("CHESSKING")
161
+
162
+ # Shogi variants
163
+ mini_shogi = Sashite::Snn::Style.parse("MINISHOGI")
164
+ handicap_shogi = Sashite::Snn::Style.parse("SHOGI9")
165
+
166
+ # Other traditions
167
+ thai_makruk = Sashite::Snn::Style.parse("MAKRUK")
168
+ korean_janggi = Sashite::Snn::Style.parse("JANGGI")
169
+ ```
170
+
171
+ ### Cross-Style Gaming
172
+
173
+ ```ruby
174
+ # Create a cross-style game setup
175
+ first_player_style = Sashite::Snn::Style.parse("CHESS")
176
+ second_player_style = Sashite::Snn::Style.parse("makruk")
177
+
178
+ puts "Game: #{first_player_style} vs #{second_player_style}"
179
+ # => "Game: CHESS vs makruk"
180
+
181
+ # This represents a unique game where chess pieces face makruk pieces
182
+
183
+ # Each player keeps their assigned style throughout the game
184
+ game_config = {
185
+ first_player: first_player_style, # Fixed: CHESS
186
+ second_player: second_player_style # Fixed: makruk
187
+ }
188
+
189
+ # Using symbols for configuration
190
+ style_configs = {
191
+ first_player_style.to_sym => { piece_set: :western, board: :"8x8" },
192
+ second_player_style.to_sym => { piece_set: :thai, board: :"8x8" }
193
+ }
194
+ ```
195
+
196
+ ## API Reference
197
+
198
+ ### Module Methods
199
+
200
+ - `Sashite::Snn.valid?(snn_string)` - Check if a string is valid SNN notation
201
+ - `Sashite::Snn.style(identifier)` - Convenience method to create style objects
202
+
203
+ ### Sashite::Snn::Style Class Methods
204
+
205
+ - `Sashite::Snn::Style.parse(snn_string)` - Parse a SNN string into a style object
206
+ - `Sashite::Snn::Style.new(identifier)` - Create a new style instance
207
+
208
+ ### Instance Methods
209
+
210
+ #### Player Queries
211
+ - `#first_player?` - Check if style belongs to first player (uppercase)
212
+ - `#second_player?` - Check if style belongs to second player (lowercase)
213
+ - `#uppercase?` - Alias for `#first_player?`
214
+ - `#lowercase?` - Alias for `#second_player?`
215
+
216
+ #### Conversion
217
+ - `#to_s` - Convert to SNN string representation
218
+ - `#to_sym` - Convert to symbol representation
219
+ - `#inspect` - Detailed string representation for debugging
220
+
221
+ ## Properties of SNN
222
+
223
+ * **Rule-agnostic**: SNN does not encode game states, legality, validity, or game-specific conditions
224
+ * **Unambiguous identification**: Different piece styles can coexist without naming conflicts
225
+ * **Canonical representation**: Equivalent styles yield identical strings
226
+ * **Cross-style support**: Enables games where players use different piece traditions
227
+ * **Case consistency**: Each identifier is entirely uppercase or entirely lowercase
228
+ * **Fixed assignment**: Style assignment to players remains constant throughout a game
229
+
230
+ ## Constraints
231
+
232
+ * SNN supports exactly **two players**
233
+ * Players are distinguished by casing: **uppercase** for first player, **lowercase** for second player
234
+ * Style identifiers must start with an alphabetic character
235
+ * Subsequent characters may include alphabetic characters and digits
236
+ * Mixed casing is not permitted within a single identifier
237
+ * Style assignment to players remains **fixed throughout a game**
238
+
239
+ ## Use Cases
240
+
241
+ SNN is particularly useful in the following scenarios:
242
+
243
+ 1. **Multi-style environments**: When games involve pieces from multiple traditions or variants
244
+ 2. **Game engine development**: When implementing engines that need to distinguish between different piece style traditions
245
+ 3. **Hybrid games**: When creating or analyzing games that combine elements from different piece traditions
246
+ 4. **Database systems**: When storing game data that must avoid naming conflicts between similar styles
247
+ 5. **Cross-tradition analysis**: When comparing or analyzing strategic elements across different piece traditions
248
+ 6. **Tournament systems**: When organizing events that allow players to choose from different piece style traditions
249
+
250
+ ## Documentation
251
+
252
+ - [Official SNN Specification](https://sashite.dev/documents/snn/1.0.0/)
253
+ - [API Documentation](https://rubydoc.info/github/sashite/snn.rb/main)
254
+
255
+ ## License
256
+
257
+ The [gem](https://rubygems.org/gems/sashite-snn) is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
258
+
259
+ ## About Sashité
260
+
261
+ This project is maintained by [Sashité](https://sashite.com/) — promoting chess variants and sharing the beauty of Chinese, Japanese, and Western chess cultures.
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sashite
4
+ module Snn
5
+ # Represents a style identifier in SNN format
6
+ #
7
+ # A style represents a particular tradition, variant, or design approach for game pieces.
8
+ # The casing of the identifier determines player association:
9
+ # - Uppercase identifiers belong to the first player
10
+ # - Lowercase identifiers belong to the second player
11
+ #
12
+ # @example
13
+ # # First player styles (uppercase)
14
+ # chess_style = Sashite::Snn::Style.new("CHESS")
15
+ # shogi_style = Sashite::Snn::Style.new("SHOGI")
16
+ #
17
+ # # Second player styles (lowercase)
18
+ # makruk_style = Sashite::Snn::Style.new("makruk")
19
+ # chess960_style = Sashite::Snn::Style.new("chess960")
20
+ class Style
21
+ # @return [String] The style identifier
22
+ attr_reader :identifier
23
+
24
+ # Create a new style instance
25
+ #
26
+ # @param identifier [String] The style identifier
27
+ # @raise [ArgumentError] if the identifier is invalid SNN notation
28
+ #
29
+ # @example
30
+ # style = Sashite::Snn::Style.new("CHESS")
31
+ # # => #<Sashite::Snn::Style:0x... @identifier="CHESS">
32
+ def initialize(identifier)
33
+ raise ArgumentError, "Invalid SNN format: #{identifier.inspect}" unless Snn.valid?(identifier)
34
+
35
+ @identifier = identifier.freeze
36
+
37
+ freeze
38
+ end
39
+
40
+ # Parse a SNN string into a style object
41
+ #
42
+ # @param snn_string [String] The SNN string to parse
43
+ # @return [Sashite::Snn::Style] A new style object
44
+ # @raise [ArgumentError] if the string is invalid SNN notation
45
+ #
46
+ # @example
47
+ # style = Sashite::Snn::Style.parse("CHESS")
48
+ # # => #<Sashite::Snn::Style:0x... @identifier="CHESS">
49
+ def self.parse(snn_string)
50
+ new(snn_string)
51
+ end
52
+
53
+ # Check if this style belongs to the first player
54
+ #
55
+ # @return [Boolean] true if the style is uppercase (first player), false otherwise
56
+ #
57
+ # @example
58
+ # Sashite::Snn::Style.new("CHESS").first_player? # => true
59
+ # Sashite::Snn::Style.new("shogi").first_player? # => false
60
+ def first_player?
61
+ uppercase?
62
+ end
63
+
64
+ # Check if this style belongs to the second player
65
+ #
66
+ # @return [Boolean] true if the style is lowercase (second player), false otherwise
67
+ #
68
+ # @example
69
+ # Sashite::Snn::Style.new("CHESS").second_player? # => false
70
+ # Sashite::Snn::Style.new("shogi").second_player? # => true
71
+ def second_player?
72
+ lowercase?
73
+ end
74
+
75
+ # Check if the style identifier is uppercase
76
+ #
77
+ # @return [Boolean] true if the identifier is uppercase, false otherwise
78
+ #
79
+ # @example
80
+ # Sashite::Snn::Style.new("CHESS").uppercase? # => true
81
+ # Sashite::Snn::Style.new("chess").uppercase? # => false
82
+ def uppercase?
83
+ identifier == identifier.upcase
84
+ end
85
+
86
+ # Check if the style identifier is lowercase
87
+ #
88
+ # @return [Boolean] true if the identifier is lowercase, false otherwise
89
+ #
90
+ # @example
91
+ # Sashite::Snn::Style.new("CHESS").lowercase? # => false
92
+ # Sashite::Snn::Style.new("chess").lowercase? # => true
93
+ def lowercase?
94
+ identifier == identifier.downcase
95
+ end
96
+
97
+ # Convert the style to its string representation
98
+ #
99
+ # @return [String] The style identifier
100
+ #
101
+ # @example
102
+ # Sashite::Snn::Style.new("CHESS").to_s # => "CHESS"
103
+ def to_s
104
+ identifier
105
+ end
106
+
107
+ # Convert the style to a symbol
108
+ #
109
+ # @return [Symbol] The style identifier as a symbol
110
+ #
111
+ # @example
112
+ # Sashite::Snn::Style.new("CHESS").to_sym # => :CHESS
113
+ def to_sym
114
+ identifier.to_sym
115
+ end
116
+
117
+ # String representation for debugging
118
+ #
119
+ # @return [String] A detailed string representation
120
+ def inspect
121
+ "#<#{self.class}:0x#{object_id.to_s(16)} @identifier=#{identifier.inspect}>"
122
+ end
123
+
124
+ # Equality comparison
125
+ #
126
+ # @param other [Object] The object to compare with
127
+ # @return [Boolean] true if both objects are Style instances with the same identifier
128
+ def ==(other)
129
+ other.is_a?(Style) && identifier == other.identifier
130
+ end
131
+
132
+ # Alias for equality comparison
133
+ alias eql? ==
134
+
135
+ # Hash code for use in hashes and sets
136
+ #
137
+ # @return [Integer] The hash code
138
+ def hash
139
+ [self.class, identifier].hash
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "snn/style"
4
+
5
+ module Sashite
6
+ # Style Name Notation (SNN) module
7
+ #
8
+ # SNN provides a consistent and rule-agnostic format for identifying piece styles
9
+ # in abstract strategy board games. It enables clear distinction between different
10
+ # piece traditions, variants, or design approaches within multi-style gaming environments.
11
+ #
12
+ # @see https://sashite.dev/documents/snn/1.0.0/ SNN Specification v1.0.0
13
+ module Snn
14
+ # SNN validation regular expression
15
+ # Matches: uppercase style (A-Z followed by A-Z0-9*) or lowercase style (a-z followed by a-z0-9*)
16
+ VALIDATION_REGEX = /\A([A-Z][A-Z0-9]*|[a-z][a-z0-9]*)\z/
17
+
18
+ # Check if a string is valid SNN notation
19
+ #
20
+ # @param snn_string [String] The string to validate
21
+ # @return [Boolean] true if the string is valid SNN notation, false otherwise
22
+ #
23
+ # @example
24
+ # Sashite::Snn.valid?("CHESS") # => true
25
+ # Sashite::Snn.valid?("shogi") # => true
26
+ # Sashite::Snn.valid?("Chess") # => false (mixed case)
27
+ # Sashite::Snn.valid?("123") # => false (must start with letter)
28
+ # Sashite::Snn.valid?("") # => false (empty string)
29
+ def self.valid?(snn_string)
30
+ return false unless snn_string.is_a?(String)
31
+ return false if snn_string.empty?
32
+
33
+ VALIDATION_REGEX.match?(snn_string)
34
+ end
35
+
36
+ # Convenience method to create a style object
37
+ #
38
+ # @param identifier [String] The style identifier
39
+ # @return [Sashite::Snn::Style] A new style object
40
+ # @raise [ArgumentError] if the identifier is invalid
41
+ #
42
+ # @example
43
+ # style = Sashite::Snn.style("CHESS")
44
+ # # => #<Sashite::Snn::Style:0x... @identifier="CHESS">
45
+ def self.style(identifier)
46
+ Style.new(identifier)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Sashité namespace for board game notation libraries
4
+ module Sashite
5
+ # Style Name Notation (SNN) implementation for Ruby
6
+ #
7
+ # SNN is a consistent and rule-agnostic format for identifying piece styles
8
+ # in abstract strategy board games. It provides unambiguous identification
9
+ # of piece styles by using standardized naming conventions, enabling clear
10
+ # distinction between different piece traditions, variants, or design
11
+ # approaches within multi-style gaming environments.
12
+ #
13
+ # @see https://sashite.dev/documents/snn/1.0.0/ SNN Specification v1.0.0
14
+ # @author Sashité
15
+ # @since 1.0.0
16
+ end
17
+
18
+ require_relative "sashite/snn"
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sashite-snn
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Cyril Kato
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |
13
+ A clean, minimal Ruby implementation of Style Name Notation (SNN) for abstract strategy games.
14
+ SNN provides a consistent and rule-agnostic format for identifying piece styles, enabling
15
+ clear distinction between different piece traditions, variants, or design approaches within
16
+ multi-style gaming environments. Features include player-based casing, style validation,
17
+ and cross-style compatibility. Perfect for game engines, multi-tradition environments,
18
+ and hybrid gaming systems.
19
+ email: contact@cyril.email
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - LICENSE.md
25
+ - README.md
26
+ - lib/sashite-snn.rb
27
+ - lib/sashite/snn.rb
28
+ - lib/sashite/snn/style.rb
29
+ homepage: https://github.com/sashite/snn.rb
30
+ licenses:
31
+ - MIT
32
+ metadata:
33
+ bug_tracker_uri: https://github.com/sashite/snn.rb/issues
34
+ documentation_uri: https://rubydoc.info/github/sashite/snn.rb/main
35
+ homepage_uri: https://github.com/sashite/snn.rb
36
+ source_code_uri: https://github.com/sashite/snn.rb
37
+ specification_uri: https://sashite.dev/documents/snn/1.0.0/
38
+ rubygems_mfa_required: 'true'
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 3.2.0
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubygems_version: 3.6.7
54
+ specification_version: 4
55
+ summary: Style Name Notation (SNN) support for the Ruby language.
56
+ test_files: []