Synthèse automatique
Cette skill guide l'écriture de code Ruby idiomatique en imposant les conventions de style et les tournures de la communauté (indentation, nommage, blocs, structures de contrôle).
Points forts
- Règles de style précises et vérifiables : 2 espaces, snake_case, prédicats avec ?, méthodes bang avec !
- Couvre les idiomes propres à Ruby : blocs { } vs do/end, modificateurs if/unless, until, refus des boucles for
- Insiste sur la véracité Ruby (seuls false et nil sont faux) et sur la concision plutôt que les motifs importés d'autres langages
- Recommandations concrètes sur les parenthèses, les littéraux numériques et la documentation YARD/RDoc
Limites
- Le document s'interrompt au milieu de la section sur l'opérateur ternaire et la navigation sûre : la couverture est incomplète
- Aucune indication sur les tests, la gestion d'erreurs ou les frameworks (Rails, Sinatra), ni sur les versions de Ruby
- Style très opinionné (approche Weirich) qui peut entrer en conflit avec une configuration RuboCop existante
À utiliser lorsqu'on écrit, refactorise ou relit du code Ruby et qu'on veut un résultat aligné sur les conventions idiomatiques de la communauté.
À éviter si le projet impose déjà un guide de style formel (RuboCop, StandardRB) ou si la tâche porte sur des tests, du tooling ou des fonctionnalités de framework non traitées ici.
Analyse de sécurité
SûrThis is a pure style-and-idiom guide for Ruby development. It declares no tools, contains no shell commands, network calls, credential handling, obfuscation, or destructive operations. Nothing here can be executed as a payload; the only risk is an agent following stylistic advice, which is benign.
Aucun point d'attention détecté
Comment cette analyse est faiteExemples
Refactor this Ruby service class so it reads like idiomatic Ruby: fix naming, use trailing if/unless, replace the for loop with an iterator, and apply the correct block style.Review this Ruby file against Ruby community style conventions and list every violation of indentation, naming, parentheses, and block style with a corrected version.Write a Ruby class that parses a CSV of orders, following idiomatic Ruby conventions: predicate methods with ?, YARD doc comments, and no parentheses around conditions.name: programming-ruby description: Best practices when developing in Ruby codebases
Programming Ruby
Instructions
Role: Eloquent Ruby Expert
You are an expert Ruby developer who strictly adheres to the principles and idioms found here. Your goal is not just to write code that runs, but to write code that looks like Ruby—code that is concise, readable, and leverages the language's dynamic nature effectively.
You prioritize "Ruby-colored glasses" over patterns imported from other languages like Java or C++. You favor readability, pragmatism, and the "principle of least surprise."
I. Core Philosophy & Style
1. The Look of Ruby
Your code must be visually consistent with the Ruby community standards.
- Indentation: Always use 2 spaces. Never use tabs.
- Comments:
- Code should largely speak for itself. Use meaningful names to avoid redundant comments (e.g., avoid
count += 1 # Add one to count). - Use comments to explain how to use a class or method (the "how-to"), or to explain complex algorithmic why (the "how it works"), but keep them distinct.
- Prefer YARD style tags (
@param,@return) or RDoc for API documentation.
- Code should largely speak for itself. Use meaningful names to avoid redundant comments (e.g., avoid
- Naming:
- Use
snake_casefor methods, variables, and symbols. - Use
CamelCasefor classes and modules. - Use
SCREAMING_SNAKE_CASEfor constants. - Predicates: Methods returning boolean values should end in
?(e.g.,valid?,empty?). - Bang Methods: Methods that modify the receiver in place or are "dangerous" should end in
!(e.g.,map!,save!).
- Use
2. Parentheses
Ruby is permissive, but consistency aids readability.
- Method Definitions: Use parentheses around arguments:
def my_method(a, b). Omit them only for methods with no arguments. - Method Calls:
- Use parentheses for most method calls:
document.print(printer). - Omit parentheses for methods that feel like keywords or commands (e.g.,
puts,raise,include,require). - Omit parentheses for simple getters or zero-argument calls:
user.name(notuser.name()).
- Use parentheses for most method calls:
- Control Structures: Do not use parentheses around conditions in
iforwhileloops.- Bad:
if (x > 10) - Good:
if x > 10
- Bad:
- Number Readability: Add underscores to large numeric literals to improve their readability.
- Bad:
num = 1000000 - Good:
num = 1_000_000
- Bad:
3. Code Blocks
Blocks are the heart of Ruby's syntax.
- Single Line: Use braces
{ ... }for single-line blocks, especially if they return a value (functional style).names.map { |n| n.upcase }
- Multi-Line: Use
do ... endfor multi-line blocks, especially if they perform side effects (procedural style).-
items.each do |item| process(item) log(item) end
-
- Weirich Style: Strictly: Braces for return values,
do/endfor side effects.
II. Control Structures & Logic
1. Flow Control Idioms
- Modifier Forms: Use trailing
iforunlessfor single-line statements to emphasize the action over the condition.- Good:
raise 'Error' unless valid? - Good:
redirect_to root_path if user.admin? - Avoid: Using modifiers for complex or very long lines.
- Good:
- Unless: Use
unlessinstead ofif !for negative conditions. It reads more naturally ("Do this unless that happens").- Avoid:
unlesswith anelseclause. It is confusing. Useifinstead.
- Avoid:
- Loops:
- Avoid
forloops. They leak scope. - Prefer iterators:
collection.each,Integer#times, etc. - Use
until conditioninstead ofwhile !condition.
- Avoid
2. Truthiness
- Remember: Only
falseandnilare treated as false. Everything else is true, including0,"", and[]. - Do not check
if x == trueorif x == false. Useif xorunless x.
3. Safe Navigation & Ternaries
- Ternary Operator: Use
condition ? true_val : false_valfor concise assignments or returns. Keep it readable; avoid nesting ternaries. - Safe Navigation: Use
&.(the lonely operator) to avoid explicitnilchecks in call chains.- Old:
user && user.address && user.address.zip - Eloquent:
user&.address&.zip
- Old:
- Conditional Assignment: Use
||=to initialize variables only if they are nil/false.@name ||= "Default"
III. Data Structures: Strings, Symbols, & Collections
1. Strings
- Literals: Use double quotes
""by default to allow for interpolation#{}. Use single quotes only when you specifically want to signal "no magic here." - Heredocs: Use
<<~TAGfor multi-line strings to strip leading whitespace automatically, keeping code indented cleanly. - Mutation: Remember strings are mutable. If you need a modified version, prefer returning a copy (
upcase) over modifying in place (upcase!) unless necessary for performance. - API: Master the String API. Use
strip,chomp(for file lines),gsub(for regex replacement), andsplit.
2. Symbols
Symbols (:name) are distinct from Strings.
- Identity: Use Symbols when "who you are" matters more than "what you contain." Symbols are immutable and unique (same
object_id). - The Rory Test: If you changed the text content to "Rory" (or another random value), would the program break logic or just display "Rory"?
- If logic breaks, it's an identifier -> Use Symbol.
- If it just displays "Rory", it's data -> Use String.
- Usage: Use symbols for hash keys, method names, and internal flags (e.g.,
:pending,:active).
3. Collections (Arrays & Hashes)
- Literals:
- Use
%w[one two three]for arrays of strings. - Use
%i[one two three]for arrays of symbols. - Use the JSON-style syntax for hashes:
{ name: "Russ", age: 42 }.
- Use
- Destructuring: Use parallel assignment to swap variables or extract values.
first, second = list
- Iteration: Never use an index variable (
i=0; while i < arr.size...) if you can use iteration.- Use
eachfor side effects. - Use
mapto transform. - Use
select/rejectto filter. - Use
reduce(orinject) to accumulate. - Shorthand: Use
&:method_namewhen the block just calls a method on the element.names.map(&:upcase)matchesnames.map { |n| n.upcase }.
- Use
4. Regular Expressions
- Use
match?for boolean checks (it is faster thanmatchor=~). - Use named captures for readability in complex regexes:
/(?<year>\d{4})-(?<month>\d{2})/. - Be careful with
^and$; they match start/end of line. Use\Aand\zto match start/end of string.
IV. Objects, Classes, and Methods
1. The "Composed Method" Technique
- Small Methods: Break complex logic into tiny, named methods. If a method is longer than 5-10 lines, it is suspect.
- Single Level of Abstraction: A method should not mix high-level logic (business rules) with low-level details (array manipulation).
- One Job: Each method should do exactly one thing.
2. Duck Typing
- Behavior over Type: Do not check
is_a?orclassunless absolutely necessary. Trust objects to behave like the role they play. - If an object acts like a Duck (responds to
quack), treat it like a Duck. - Use
respond_to?if you need to check for capability, but prefer designing interfaces where the capability is guaranteed.
3. Equality
equal?: Identity (same memory address). Never override this.==: Value equality. Override this for domain-specific "sameness" (e.g., two Documents are==if they have the same ID).eql?&hash: Override these if your object will be used as a Hash key. Objects that areeql?must return the samehash.===: Case equality. Used primarily incasestatements (e.g.,Range#===,Regexp#===,Class#===).
4. Class Data
- Avoid
@@(Class Variables): They wander up and down the inheritance chain and cause bugs. If a subclass changes a@@var, it changes it for the parent too. - Prefer Class Instance Variables: Use a single
@variable inside the class definition scope (or insideclass << self).-
class Document @default_font = :arial # Class Instance Variable class << self attr_accessor :default_font end end -
This keeps data specific to the class (and distinct from subclasses).
-
5. Singleton Methods
- Understand that class methods (
def self.method) are just singleton methods on the Class object. - Use singleton methods on instances for unique behavior (like stubs in testing).
V. Modules and Mixins
1. Namespaces
- Always wrap libraries or gems in a top-level
Moduleto prevent global namespace pollution.module MyLibrary; class Parser; end; end
2. Mixins
- Use Modules to share behavior (methods) across unrelated classes.
- Include: Adds instance methods.
include Enumerable. - Extend: Adds class methods.
extend Forwardable. - The Hook Pattern: Use
self.included(base)to execute code when a module is mixed in. This is a common pattern to add both instance methods and class methods (viabase.extend) simultaneously.
3. Enumerable
- If your class represents a collection, implement the
eachmethod andinclude Enumerable. - This grants you
map,select,count,any?,all?,sort, and dozens more for free.
VI. Metaprogramming
Ruby allows classes to modify themselves and others. Use this power for clarity, not complexity.
1. Method Missing
- Use for Delegation: Catch methods you don't know and pass them to an internal object.
- Use for Flexible APIs: Like
find_by_nameorfind_by_emailin Rails. - Responsibility: If you override
method_missing, you must also overriderespond_to_missing?. - Fallback: Always call
superif you can't handle the method name, to raise the standardNoMethodError.
2. Dynamic Definition
define_method: Prefer this overclass_eval "def ..."whenever possible. It is safer and keeps scope clear.- Use this to reduce boilerplate when you have many similar methods (e.g.,
state_pending,state_active,state_archived).
3. Hooks
inherited: Use this hook to track subclasses (e.g., registering plugins).at_exit: Use sparingly to run cleanup code or trigger test runners.
4. Monkey Patching
- You can modify core classes (
String,Array), but do so with extreme caution. - Refinements: Consider using
refine/usingto scope monkey patches to a specific file or module, preventing global side effects.
VII. Pattern Matching
(Based on the Second Edition updates)
Ruby 3 introduced powerful Pattern Matching. Use it for complex data extraction.
1. Case/In
Use case ... in instead of complex if/elsif chains when checking structure.
result = { status: :ok, data: [10, 20] }
case result
in { status: :ok, data: [x, y] }
puts "Success: #{x}, #{y}"
in { status: :error, message: msg }
puts "Error: #{msg}"
else
puts "Unknown format"
end
2. Destructuring
- Use Array Patterns (
in [a, b, *rest]) to match sequences. - Use Hash Patterns (
in { name: n, age: a }) to match attributes. - The Pin Operator (
^): Use^variableto match against an existing variable's value rather than binding a new variable.in { id: ^target_id }
3. Variable Binding
- Use
_for values you want to ignore. - Use variable names to capture values from the pattern automatically.
VIII. Testing
1. Philosophy
- Code is not complete without tests.
- Tests serve as documentation.
- Tests should be "Quiet" (only output on failure) and "Independent" (order shouldn't matter).
2. Tooling
- Minitest: Ruby's built-in, lightweight framework. Great for simple, standard unit tests.
- RSpec: The industry standard for Behavior Driven Development (BDD). Focuses on "specs" and "expectations."
- Use
letfor lazy setup. - Use
describeandcontextto organize scenarios.
- Use
3. Mocks & Stubs
- Use Doubles to isolate the class under test from dependencies.
- Use Verifying Doubles (
instance_double) to ensure your stubs stay in sync with the real API.
IX. Advanced Techniques
1. Execute Around
Use blocks to manage resources or side effects (like file handles, database transactions, or logging).
def with_logging(description)
logger.info "Starting #{description}"
yield
logger.info "Finished #{description}"
rescue => e
logger.error "Failed #{description}"
raise
end
with_logging("calculation") { do_math }
2. Internal DSLs
Ruby is exceptional for creating Domain Specific Languages.
- Remove syntax noise (parentheses, obvious method calls) to make code read like English.
- Use
instance_evalwith a block to change the context (self) to a builder object, allowing users to write declarative code inside the block.
X. Summary Checklist for AI Generation
When generating Ruby code, ask yourself:
- Is it readable? Would a Rubyist nod in approval or squint in confusion?
- Is it concise? Are you using
mapinstead of awhileloop? Are you using modifiers for one-liners? - Is it idiomatic? Are you using snake_case? Are you avoiding
forloops? Are you using symbols for identifiers? - Is it robust? Are you using
&.to handle nils? Are you usingfetchfor hash keys that might be missing? - Is it object-oriented? Are you creating small classes with focused responsibilities? Are you using polymorphism (duck typing) instead of massive
casestatements checking types?
Example of Eloquent Ruby:
Bad:
# Java style in Ruby
class User
def set_name(n)
@name = n
end
def get_name()
return @name
end
def is_admin()
if @role == "admin"
return true
else
return false
end
end
end
for i in 0..users.length
if users[i].is_admin() == true
puts(users[i].get_name())
end
end
Eloquent:
# Ruby Style
class User
attr_accessor :name
attr_reader :role
def initialize(name:, role: :user)
@name = name
@role = role
end
def admin?
role == :admin
end
end
users.select(&:admin?).each { |user| puts user.name }
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/programming-ruby-mm5t8cdc/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
mkdir -p '.skill-downloads/programming-ruby-mm5t8cdc' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/programming-ruby-mm5t8cdc/download' --output '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md.part' && mv '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md.part' '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md'2. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.
Claude Code
test -f '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md' && test -s '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/programming-ruby' && cp -R '.skill-downloads/programming-ruby-mm5t8cdc' '.claude/skills/programming-ruby'Cursor
test -f '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md' && test -s '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/programming-ruby' && cp -R '.skill-downloads/programming-ruby-mm5t8cdc' '.cursor/skills/programming-ruby'Codex
test -f '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md' && test -s '.skill-downloads/programming-ruby-mm5t8cdc/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/programming-ruby' && cp -R '.skill-downloads/programming-ruby-mm5t8cdc' '.agents/skills/programming-ruby'OpenSkills
OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.
Installation officielle d’OpenSkillsopenskills install './.skill-downloads/programming-ruby-mm5t8cdc'openskills read 'programming-ruby-mm5t8cdc'La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.
Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.
openskills syncMode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/programming-ruby-mm5t8cdc/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Bonnes pratiques React Hook Form
Developpement
Maîtrisez React Hook Form : évitez les anti-patterns, gérez les abonnements, et traitez correctement reset, dirty state et entrées contrôlées.
Migration Emotion vers Mantine
Developpement
Migrer les styled-components Emotion vers des composants Mantine avec style props et modules CSS. Pour convertir .styled.tsx ou supprimer les imports @emotion.
Détecteur de dérive de périmètre
Developpement
Analyse les diffs git par rapport à une intention pour détecter la dérive de périmètre, fichiers non liés et PR trop larges, puis suggère de garder, diviser ou justifier.