injectable icon indicating copy to clipboard operation
injectable copied to clipboard

Poor Man's Type Checking in Arguments and Returns

Open julitrows opened this issue 3 months ago • 2 comments

Please, disregard the branch name 😮‍💨

Changes

Add optional type checking to argument declarations

argument :jarl, type: Chiquito
argument :torpedo, type: Array, default: nil

Add optional type checking to returned values

returns MyClass, nullable: true
returns MyCollection, of: Item, nullable: true, allow_nils: false

Notes

Made them optional, since they're not the main purpose of the library, but happy to cut a 3.0.0 branch with breaking changes.

See each commit's README entries for more examples

class UserByPermissionsQuery
  include Injectable
  
  argument(:permission, type: Permission)
  dependency(:base_relation) { User.all }
  returns(ActiveRecord::Associations::CollectionProxy, of: User, nullable: false, allow_nils: false)

  def call
    base_relation.includes(:permissions).where(permissions: { id: permission.id })
  end
end

About Collection validations

I've got a bit of a mess there. Not really sure I should check for Enumerable, or just responds_to?(:each) is enough?

Maybe having an optional enumerates_with: key is cool to indicate which method is used to iterate the collection (default :each)?

returns MyCollection, of: Item, enumerates_with: :each, nullable: false, allow_nils: false

julitrows avatar Nov 10 '25 17:11 julitrows

Not a review, but to answer some of your questions:

Made them optional, since they're not the main purpose of the library, but happy to cut a 3.0.0 branch with breaking changes.

My idea originally was for it to be opt-in, since it has a runtime performance hit (not sure how much, but it's doing more work than before), and not everyone wants/likes strong typing.

I've got a bit of a mess there. Not really sure I should check for Enumerable, or just responds_to?(:each) is enough?

Maybe having an optional enumerates_with: key is cool to indicate which method is used to iterate the collection (default :each)?

I thought you'd do a collection.all? { it.is_a? type }. In Enumerable those are still defined in terms of :each, so I think it's a fair assumption. Still, I would assume that if someones uses of: that they're passing a collection and I would assume :each. I'd start simple and add complexity as you need it, so I'd personally keep : enumerates_with in the back burner.

iovis avatar Nov 10 '25 23:11 iovis

@iovis WDYT?

julitrows avatar Nov 20 '25 10:11 julitrows