In certain cases `rbs prototype rb` defines the wrong type definition for `Object Class`
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 2.2k
- Forks
- 256
- Avg merge
- 6d 17h
- Merged PRs (30d)
- 37
Description
The following outputs results that rbs prototype rb does not expect.
$ cat on_load.rb
class MyClass; end
# Include (lazy) MyClass in ActiveRecord::Base
# ActiveSupport.on_load uses class_eval internally.
# https://github.com/rails/rails/blob/66099147482ea431febf20936cec903f197d24be/activesupport/lib/active_support/lazy_load_hooks.rb
ActiveSupport.on_load(:active_record) { include MyClass }
$ rbs prototype rb on_load.rb -o sig --force
Processing `on_load.rb`...
Generating RBS for `on_load.rb`...
- Writing RBS to existing file `sig/on_load.rbs`...
$ cat sig/on_load.rbs
class MyClass
end
# Unspecified `include` without a receiver generates a type definition that treats the `Object` as included.
# https://github.com/ruby/rbs/blob/0b5eb4197c1dc2c09be0c43e99d8f17ac74004ad/lib/rbs/prototype/rb.rb#L47-L62
class Object
include MyClass
end
This is true not only for include but also for extend and prepend.
This is a problem because if rbs prototype accidentally defines an Object type, there is no way around it even if you manually override the type.
The rbs prototype will not know the inner workings of ActiveSupport.on_load and will have difficulty resolving the root cause.
For example, what if the behavior of the rbs prototype command is to ignore includes in method blocks (and extend, prepend...) in a method block (and extend, prepend...) should be ignored.
(Careful decision making is required as this would be an incompatible change.)
Workaround
This problem can be avoided by specifying an include receiver.
However, you need to manually define the type of include to ActiveRecord::Base.
$ cat on_load.rb
class MyClass; end
ActiveSupport.on_load(:active_record) { ActiveRecord::Base.include(MyClass) } # ActiveRecord::Base or self
$ rbs prototype rb on_load.rb -o sig --force
Processing `on_load.rb`...
Generating RBS for `on_load.rb`...
- Writing RBS to existing file `sig/on_load.rbs`...
$ cat sig/on_load.rbs
class MyClass
end
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the case with rbs prototype rb on_load.rb -o sig --force, then inspect lib/rbs/prototype/rb.rb around lines 47-62, where receiverless include handling is described. Compare the generated sig/on_load.rbs for include, extend, and prepend cases; done means the agreed behavior is implemented without an unintended Object definition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100