Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Language-specific super-code guidelines for ruby.
.claude/skills/lingxling-ruby/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 115% | 0% |
| case-19 | ✓→✓ | = Same ✓ | 537% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 241% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 69% | 0% |
ruby# ❌ Manual accumulation result = [] items.each do |item| result << item.name.upcase if item.active? end # ✅ result = items.select(&:active?).map { |i| i.name.upcase }
ruby# ❌ Manual grouping grouped = {} items.each do |item| grouped[item.category] ||= [] grouped[item.category] << item end # ✅ grouped = items.group_by(&:category)
ruby# ❌ Manual sum total = 0 orders.each { |o| total += o.amount } # ✅ total = orders.sum(&:amount)
ruby# ❌ Checking existence then accessing if hash.key?(key) value = hash[key] end # ✅ value = hash[key] # returns nil if missing # or with default: value = hash.fetch(key, default_value) # or raising on missing: value = hash.fetch(key) # raises KeyError
Prefer map/select/reject/sum over manual loops. Use &:method for single-method blocks.
ruby# ❌ Explicit block-to-proc conversion when unnecessary items.map { |item| item.to_s } # ✅ items.map(&:to_s)
ruby# ❌ Proc.new when lambda is safer (arity check + return behavior) handler = Proc.new { |x| x * 2 } # ✅ handler = ->(x) { x * 2 }
ruby# ❌ Multi-line block with { } items.map { |item| result = transform(item) validate(result) result } # ✅ — do/end for multi-line, { } for single-line items.map do |item| result = transform(item) validate(result) result end
ruby# ❌ String concatenation in loop result = "" items.each { |i| result += i.name + ", " } # ✅ result = items.map(&:name).join(", ")
ruby# ❌ String concatenation for assembly greeting = "Hello, " + name + "! You have " + count.to_s + " messages." # ✅ greeting = "Hello, #{name}! You have #{count} messages."
ruby# ❌ Mutable string where frozen is fine (Ruby 3+ encourages frozen) SEPARATOR = ", " # ✅ SEPARATOR = ", ".freeze # or add `# frozen_string_literal: true` at file top
Use heredocs (<<~HEREDOC) for multi-line strings. <<~ strips indentation.
ruby# ❌ Rescuing Exception (catches EVERYTHING including SignalException, SystemExit) begin risky rescue Exception => e log(e) end # ✅ — rescue StandardError (the default) begin risky rescue StandardError => e log(e) raise end # or just: rescue => e (same as StandardError)
ruby# ❌ Using rescue as flow control begin value = hash.fetch(key) rescue KeyError value = default end # ✅ value = hash.fetch(key, default)
ruby# ❌ Inline rescue hiding errors result = dangerous_operation rescue nil # ✅ — inline rescue only for truly trivial fallbacks result = Integer(input) rescue nil # acceptable for parsing
ruby# ❌ Manual accessors class User def name @name end def name=(value) @name = value end end # ✅ class User attr_accessor :name end
ruby# ❌ Deep inheritance for shared behavior class Animal; end class Pet < Animal; end class Dog < Pet; end # ✅ — mixins for shared behavior, inheritance for "is-a" module Trainable def train = puts("Training #{name}") end class Dog include Trainable attr_reader :name def initialize(name) = @name = name end
ruby# ❌ Class with only class methods (namespace via class) class MathUtils def self.square(x) = x * x def self.cube(x) = x ** 3 end # ✅ module MathUtils module_function def square(x) = x * x def cube(x) = x ** 3 end
ruby# ❌ Explicit boolean return def active? if status == :active true else false end end # ✅ def active? = status == :active
ruby# ❌ nil check before method call if user && user.name puts user.name end # ✅ (Ruby 2.3+) puts user&.name if user&.name # or with safe navigation: user&.name&.then { |n| puts n }
ruby# ❌ Conditional assignment verbosely if @cache.nil? @cache = expensive_compute end # ✅ @cache ||= expensive_compute
ruby# ❌ Multiple assignment from array manually first = arr[0] second = arr[1] # ✅ first, second = arr
| Anti-pattern | Preferred | |---|---| | rescue Exception | rescue StandardError | | for x in collection | collection.each | | Manual attr_reader/writer | attr_accessor / attr_reader | | class for pure namespace | module | | String concatenation with + | string interpolation #{} | | if !condition | unless condition | | == true / == false | truthy/falsy check directly | | and/or for control flow | &&/|| (different precedence) | | return at end of method | implicit return (last expression) | | Monkey-patching core classes in production | refinements or wrapper | | eval / send for known methods | direct method call |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 9,483 | 26,301 | +177% | 1 | 1 | 0% | 1,751 | 2,976 | +70% | 0 | 0 | — |
case-02 | fail→pass | 5,943 | 4,384 | -26% | 1 | 1 | 0% | 1,206 | 2,591 | +115% | 0 | 0 | — |
case-19 | pass→pass | 2,772 | 3,848 | +39% | 1 | 1 | 0% | 374 | 2,381 | +537% | 0 | 0 | — |
case-03 | pass→pass | 4,091 | 2,789 | -32% | 1 | 1 | 0% | 648 | 2,207 | +241% | 0 | 0 | — |
case-04 | pass→pass | 8,291 | 3,729 | -55% | 1 | 1 | 0% | 1,377 | 2,330 | +69% | 0 | 0 | — |
case-05 | pass→pass | 14,252 | 7,523 | -47% | 1 | 1 | 0% | 2,841 | 3,210 | +13% | 0 | 0 | — |
case-06 | pass→pass | 2,441 | 2,484 | +2% | 1 | 1 | 0% | 391 | 2,031 | +419% | 0 | 0 | — |
case-07 | pass→pass | 8,784 | 4,170 | -53% | 1 | 1 | 0% | 1,572 | 2,463 | +57% | 0 | 0 | — |
case-08 | pass→pass | 3,059 | 2,832 | -7% | 1 | 1 | 0% | 555 | 2,178 | +292% | 0 | 0 | — |
case-09 | pass→pass | 5,875 | 2,951 | -50% | 1 | 1 | 0% | 1,002 | 2,231 | +123% | 0 | 0 | — |
case-10 | pass→pass | 3,831 | 3,287 | -14% | 1 | 1 | 0% | 595 | 2,174 | +265% | 0 | 0 | — |
case-11 | pass→pass | 3,683 | 2,863 | -22% | 1 | 1 | 0% | 613 | 2,127 | +247% | 0 | 0 | — |
case-12 | pass→pass | 5,539 | 3,752 | -32% | 1 | 1 | 0% | 980 | 2,365 | +141% | 0 | 0 | — |
case-13 | pass→pass | 3,764 | 3,460 | -8% | 1 | 1 | 0% | 619 | 2,288 | +270% | 0 | 0 | — |
case-14 | pass→pass | 5,734 | 4,595 | -20% | 1 | 1 | 0% | 1,011 | 2,546 | +152% | 0 | 0 | — |
case-15 | pass→pass | 3,903 | 2,745 | -30% | 1 | 1 | 0% | 670 | 2,160 | +222% | 0 | 0 | — |
case-16 | pass→pass | 4,859 | 5,083 | +5% | 1 | 1 | 0% | 844 | 2,560 | +203% | 0 | 0 | — |
case-17 | pass→pass | 2,845 | 2,013 | -29% | 1 | 1 | 0% | 484 | 2,078 | +329% | 0 | 0 | — |
case-18 | pass→pass | 4,016 | 3,704 | -8% | 1 | 1 | 0% | 794 | 2,360 | +197% | 0 | 0 | — |
case-20 | pass→pass | 7,258 | 4,923 | -32% | 1 | 1 | 0% | 1,271 | 2,481 | +95% | 0 | 0 | — |
case-21 | pass→pass | 2,414 | 2,285 | -5% | 1 | 1 | 0% | 416 | 2,103 | +406% | 0 | 0 | — |
case-22 | pass→pass | 7,060 | 4,673 | -34% | 1 | 1 | 0% | 1,302 | 2,520 | +94% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.