Skip to content

Conversation

@joeldrapper
Copy link
Collaborator

@joeldrapper joeldrapper commented Oct 16, 2025

This PR introduces a Binding patch that allows you to make assertions about local variables at any point.

def add(a, b)
  binding.assert(a: Numeric, b: Numeric)
  a + b
end

You would ideally include Literal::Types into Object if you wanted to make the best use of this, since otherwise the _ types are not available in the context of an instance.

It would be nice if there was an equally clean way to make assertions about instance variables.

lib/literal.rb Outdated
def assert(**kwargs)
kwargs.each do |name, type|
value = local_variable_get(name)
Literal.check(value, type)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can add more context to the error message since we know what the key was.

@fractaledmind
Copy link
Collaborator

Things to consider adding:

  • asserting against instance variables
  • asserting against class variables
  • asserting against global variables

PR also needs some minimal docs explaining how the method works (what error it raises if an assertion fails, what kinds of types you can pass, etc.)

But, this feels like a perfect next step for Literal. I love it

@joeldrapper joeldrapper force-pushed the push-lkwxpzkmyvyt branch 4 times, most recently from 4c5ee73 to 8edcea7 Compare October 16, 2025 23:29
@joeldrapper joeldrapper changed the title Binding assertions Runtime assertions with binding.assert Oct 17, 2025
end
end

::Binding.include(Literal::BindingAssert)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We should make a literal/pure entry point that people can use if they want to opt out of patches.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Personally would rather opt-in than opt-out, eg literal/binding_assert

Copy link
Collaborator

Choose a reason for hiding this comment

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

Elaborate? It has no perf cost, no overhead. And this DX is superior to Literal.assert(binding, **constraints).

Copy link
Collaborator

Choose a reason for hiding this comment

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

It is mixing something in Binding, which I would find somewhat unexpected unless I explicitly wanted that feature

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think the main use case will be people opting in. I was only thinking of adding /pure for gem authors who might not want a transient dependency to do patching.

Copy link
Collaborator

@fractaledmind fractaledmind left a comment

Choose a reason for hiding this comment

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

I think this is a great feature that needs one more pass to be ready.

value = INSTANCE_VARIABLE_GET_METHOD.bind_call(bind.receiver, name)
end
elsif first_byte == 36 # $foo
raise if string_name.match?(/[\s\.]/)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Need to raise a named exception here with a clear message.

end

unless type === value
raise ::TypeError.new(<<~MESSAGE)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Joel and I discussed that Literal::TypeError needs a refactor to be more generic to allow for simpler errors like this. Personally, I think make TypeError simple like this and move the property stuff into a PropertyError class that inherits from TypeError

Copy link
Collaborator

Choose a reason for hiding this comment

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

Great idea

Co-authored-by: Stephen Margheim <[email protected]>
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.

4 participants