i create some dsl like this:
class Bla
def add(method, &block : -> U) forall U
p "added #{method} #{block}"
end
def some1(&block)
add("some1", &block)
end
def some2(&block)
add("some2", &block)
end
end
bla = Bla.new
bla.some1 { 1 }
bla.some2 { 2 }
"added some1 #
"added some2 #
This is ok, but i don't want to define methods some1, some2, ...
How i can do it with method_missing?
class Bla
def add(method, &block : -> U) forall U
p "added #{method} #{block}"
end
macro method_missing(call)
add({{call.name.stringify}}, &{{call.block}})
end
end
bla = Bla.new
bla.some1 { 1 }
bla.some2 { 2 }
Error in line 6: macro didn't expand to a valid program, it expanded to:
================================================================================
--------------------------------------------------------------------------------
1. add("some1", &do
2. yield
3. end)
4.
--------------------------------------------------------------------------------
Syntax error in expanded macro: method_missing:1: expecting token ')', not 'NEWLINE'
add("some1", &do
^
It seems there's no way to do that right now. To fix this I'll try this: method_missing's generated content can also be a def. If so, it's used as the method to generate. In that way you could specify the block argument. I'll probably send a PR and link this.
@kostya The solution I have in mind in this (I'll soon send a PR):
class Bla
def add(method, &block : -> U) forall U
p "added #{method} #{block}"
end
macro method_missing(call)
def {{call.name}}(&block : -> U) forall U
add({{call.name.stringify}}, &block)
end
end
end
bla = Bla.new
bla.some1 { 1 }
bla.some2 { 2 }
You can see method_missing is generating a method definition, so you can specify the captured block, if any, and its types.
I'm curious about your use case. In your DSL all methods capture the block? What is your real program?
my real program is trying to create stubs like rr: https://github.com/rr/rr
@kostya Cool! In any case I think #3610 is general enough to worth merging it, regardless of the use case (I was just curious)
Most helpful comment
It seems there's no way to do that right now. To fix this I'll try this:
method_missing's generated content can also be adef. If so, it's used as the method to generate. In that way you could specify the block argument. I'll probably send a PR and link this.