Skip to content

Conversation

@cardmagic
Copy link
Owner

Summary

Migrates type signatures from separate sig/*.rbs files to inline RBS annotations using the rbs-inline gem.

Changes

  • Add # rbs_inline: enabled and #: / @rbs annotations to source files
  • Remove 8 separate sig/*.rbs files
  • Add rbs-inline as dev dependency
  • Update CI to generate RBS from source before validation
  • Configure RuboCop AllowRBSInlineAnnotation: true

Example

# Before: sig/classifier/bayes.rbs
def classify: (String text) -> String

# After: lib/classifier/bayes.rb
# @rbs (String) -> String
def classify(text)

Notes

  • Stdlib extensions (Array, Vector, Matrix) use @rbs skip to avoid generic parameter conflicts
  • GSL types use untyped since they're optional dependencies

Fixes #57

- Add rbs-inline annotations to source files
- Remove separate sig/*.rbs files (now generated from source)
- Update CI to generate RBS with rbs-inline before validation
- Configure RuboCop to allow #: inline annotation syntax
- Skip RBS generation for stdlib extensions (Array, Vector, Matrix)
  to avoid generic parameter conflicts

Fixes #57
Updated method signatures in lsi.rb and word_hash.rb to include proper
parameter types instead of empty (). Methods now have full type signatures
like `# @RBS (String, ?Float) -> ReturnType` instead of `# @RBS () -> ReturnType`.

This completes the migration to inline RBS annotations with proper types
for all method parameters.
- Add steep gem for static type analysis
- Create Steepfile configuration (ignoring stdlib extension files and
  complex LSI dual-mode code for now)
- Add vendor RBS stubs for fast-stemmer, GSL, and Matrix dependencies
- Fix type issues in Bayes#classify (handle nil from min_by)
- Fix respond_to_missing? to return proper boolean
- Add steep check to CI workflow
@cardmagic cardmagic requested a review from Copilot December 27, 2025 10:49
@cardmagic cardmagic self-assigned this Dec 27, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates RBS type signatures from separate .rbs files to inline annotations using the rbs-inline gem. The migration removes 8 separate signature files and adds inline type annotations directly in Ruby source files, improving code locality and maintainability.

Key Changes:

  • Removed 8 separate .rbs signature files and added inline @rbs annotations to source files
  • Added rbs-inline as a development dependency and updated CI to generate RBS from inline annotations
  • Configured RuboCop to allow RBS inline annotations and added Steepfile for type checking

Reviewed changes

Copilot reviewed 19 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
sig/classifier/lsi/word_list.rbs Removed separate RBS type definitions for WordList class
sig/classifier/lsi/content_node.rbs Removed separate RBS type definitions for ContentNode class
sig/classifier/lsi.rbs Removed separate RBS type definitions for LSI class
sig/classifier/extensions/vector.rbs Removed separate RBS type definitions for Array, Vector, and Matrix extensions
sig/classifier/extensions/string.rbs Removed separate RBS type definitions for String extensions
sig/classifier/extensions/object.rbs Removed separate RBS type definitions for Object extensions
sig/classifier/bayes.rbs Removed separate RBS type definitions for Bayes class
sig/classifier.rbs Removed separate RBS module declaration
lib/classifier/lsi/word_list.rb Added inline RBS annotations for WordList class methods and instance variables
lib/classifier/lsi/content_node.rb Added inline RBS annotations for ContentNode class methods and instance variables
lib/classifier/lsi.rb Added inline RBS annotations for LSI class methods and instance variables
lib/classifier/extensions/word_hash.rb Added inline RBS annotations for String extensions
lib/classifier/extensions/vector.rb Added @rbs skip directives for Array, Vector, and Matrix classes
lib/classifier/bayes.rb Added inline RBS annotations for Bayes class methods and instance variables, with minor code improvements
classifier.gemspec Added rbs-inline as a development dependency
Steepfile Added new Steepfile configuration for type checking with ignores for stdlib extensions
Gemfile Added conditional steep gem dependency for Ruby < 4.0
.rubocop.yml Configured RuboCop to allow RBS inline annotations
.github/workflows/ruby.yml Updated CI to generate RBS from inline annotations and run type checking

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

:lsi_vector, :lsi_norm,
:categories
# @rbs @word_hash: Hash[Symbol, Integer]
# @rbs @categories: Array[String | Symbol]
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instance variable @categories is declared twice with identical RBS annotations on lines 13 and 21. Remove the duplicate annotation on line 13.

Suggested change
# @rbs @categories: Array[String | Symbol]

Copilot uses AI. Check for mistakes.
# @rbs (String) -> String
def classify(text)
classifications(text).min_by { |a| -a[1] }[0]
(classifications(text).min_by { |a| -a[1] } || []).first.to_s
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback || [] when min_by returns nil will cause .first to return nil, and then .to_s will convert it to an empty string. This differs from the original behavior which would have raised an error. The return type annotation indicates this should return a String, but the behavior when there are no classifications is now different.

Suggested change
(classifications(text).min_by { |a| -a[1] } || []).first.to_s
best = classifications(text).min_by { |a| -a[1] }
raise StandardError, "No classifications available for the given text" unless best
best.first.to_s

Copilot uses AI. Check for mistakes.
- name: Install RBS
run: gem install rbs
- name: Generate RBS from inline annotations
run: bundle exec rbs-inline --output sig lib/
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RBS generation step should run before the test step to ensure type signatures are generated before tests run. Currently, tests run on line 47 before RBS generation on line 49, which means tests execute without the generated type signatures.

Copilot uses AI. Check for mistakes.
@cardmagic cardmagic merged commit 723d025 into master Dec 27, 2025
5 checks passed
@cardmagic cardmagic deleted the refactor/rbs-inline branch December 27, 2025 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate from separate RBS files to inline RBS type annotations

2 participants