Wrote up a little blog post on something I learned today from the standard library for my own needs.
Nice blog post!
You might enjoy this one then: It's a typeof magic - The Crystal Programming Language
@asterite I’m curious if you know the reason behind the problem I’m experiencing.
So my blog post details how to make a method migrate a generic from T
to T!
but now I’m working on going from A
to B
with a map method that will work for nilable and non-nilable types (using an overlaod for the mapping).
I’m using a macro in one method to do a if-else based on whether or not the generic type is nilable. I found out that if I try to reference a block argument in the macro it fails but referencing regular arguments works as expected.
Here’s a simple example showing a method working that references a regular parameter and a method that fails to compile since it references the block argument. I got around this in my code by assigning the block to a temporary variable and referencing that variable instead.
def foo(x : T) : String forall T
{% if T.nilable? %}
"nilable: #{x}"
{% else %}
"non-nilable: #{x}"
{% end %}
end
foo("abc")
foo("def".as(String?))
def bar(x : T, &block : -> String) : String forall T
{% if T.nilable? %}
"nilable: #{block.call}"
{% else %}
"non-nilable: #{block.call}"
{% end %}
end
bar("abc") { "hello" }
bar("def".as(String?)) { "goodbye" }
Do you know what the problem is here? Or maybe it’s just a bug
Reduced:
def bar(&block : -> String) : Nil
{% begin %}
block.call
{% end %}
end
bar { "hello" }
> 1 |
> 2 | block.call
^----
Error: undefined local variable or method 'block' for top-level
Sure just seems like a bug to me? Of course in this example you can use yield
which doesn’t have this problem.
Nice post! But couldn’t you work with a non-nil type as generic argument instead, and add the Nil type inside? Something like
class Parser(T)
getter input : T?
...
end
The example in the blog post was very very simple. In my real code, I’m holding onto a proc that will parse the input and allowing multiple method calls that affect the return type of the proc. So going from nilable to non-nil, string to number, etc