Sorbet asking a `sig` for `attr_reader`
Asked Answered
V

3

9

Sorbet is showing an error for the attr_reader, but correct me if I am wrong, sigs are required when the function is declared, not called, right?

I have tried going through the documentation but all I got is this note

Note: Many Ruby constructs that look like local variables are actually method calls without parens! Specifically, watch out for attr_reader and zero-argument method definitions.

app/util/hodor.rb:125: This function does not have a `sig` https://sorbet.org/docs/error-reference#7017
     125 |  attr_reader(:collection_name)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Vidar answered 19/6, 2019 at 12:7 Comment(3)
Where does this line of code appear? They normally are contained in class or module definitions.Impulsive
Hm, sorbet playground doesn't give this errorAdaadabel
This error is silenced in all strictness levels below # typed: strict. The playground defaults to # typed: true if no sigil is given. In all other places Sorbet defaults to # typed: false if no sigil is given. sorbet.org/docs/staticPassion
A
7

The error does not have to do with the attr_reader method itself needing a sig, but with :collection_name. The signature for attr_reader is already known, but the new method it dynamically creates, #collection_name does not have a known sig, and Sorbet expects this to be the place where you give it one.

You can do this to fix it:

sig { returns(String) }
attr_reader(:collection_name)
Andesite answered 20/6, 2019 at 15:16 Comment(1)
Is it correct that an attr_reader that defines multiple attributes will have to be split up over multiple lines to make the signatures work correctly?Gird
P
1

attr_reader(attribute) is the equivalent of :

def attribute
  @attribute
end

This is probably why Sorbet is asking for a sig.

Peekaboo answered 19/6, 2019 at 12:54 Comment(0)
S
1

Here's the Sorbet documentation on it:

It goes something like this:

# typed: true
class A
  extend T::Sig

  sig {returns(Integer)}
  attr_reader :reader

  sig {params(writer: Integer).returns(Integer)}
  attr_writer :writer

  # For attr_accessor, write the sig for the reader portion.
  # (Sorbet will use that to write the sig for the writer portion.)
  sig {returns(Integer)}
  attr_accessor :accessor

  sig {void}
  def initialize
    @reader = T.let(0, Integer)
    @writer = T.let(0, Integer)
    @accessor = T.let(0, Integer)
  end
end
Stays answered 25/3, 2022 at 1:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.