Following is the spec output for one of my shards, i consider it can describe my issue quite directly.
Showing last frame. Use --error-trace for full trace.
In spec/hashr_spec.cr:22:11
22 | value.foo.should eq h
^--
Error: wrong method_missing expansion
The method_missing macro expanded to:
1 | def foo
2 | value = @obj["foo"]
3 |
4 | Hashr.new(value)
5 | end
6 |
7 | def foo=(value)
8 | @obj["foo"] = value
9 | end
10 |
However, it should only expand to a single def
so, method_missing can only create a single method, right?
If i want to create two method at one-off i method missing macro, how can i do that?
Can you create a minimal example of what your code currently does versus what you want it to do? It’s not entirely clear from just looking at this error.
Ahh, well good question. I tried just using two method_missing calls and got:
The method_missing macro expanded to:
1 | def blah=(value)
2 | pp value
3 | end
4 |
However, the generated method won't be found by the original call invocation
You can create each def by itself casing on the usage.
class A
@hash = Hash(String, Int32).new
macro method_missing(call)
{% if call.name.ends_with? "=" %}
def {{call.name}}(value)
@hash[{{call.name.gsub(/=/, "").stringify}}] = value
end
{% else %}
def {{call.name}}
@hash[{{call.name.stringify}}]
end
{% end %}
end
end
a = A.new
a.value = 5
p a.value # => 5
EDIT: quick hack, please add the corresponding checks to make sure it won’t blow out in your face!
Not work for me when test on 1.9.2, raise following error when a.phone = “xxx”,
There was a problem expanding macro 'method_missing'
Called macro defined in src/hashr.cr:19:3
19 | macro method_missing(key)
Which expanded to:
> 1 |
> 2 | def phone = _arg0(value)
> 3 | @obj["phone"] = value
> 4 | end
> 5 |
> 6 |
Error: unexpected token: "="
Well, given the error I would assume your code is not entirely faithful to what I posted, but I can’t help much without further context You can print/debug the macro code with something like {% p! call.name %} to know what you’re getting.
Oops, my fault, i am not try your code directly, instead of, i follow your’s ideas, change code directly on my shard, and run spec, it failed because i misunderstood the call.name with call.id, some part of my code use call.id instead, which cause issue.
It works now like a charm! i release v0.3 hashr just now, it can also be used as a models object now.