Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: no overload matches 'Redis#namespaced' with type Array(Redis::RedisValue) #100

Closed
kostya opened this issue Feb 17, 2020 · 2 comments

Comments

@kostya
Copy link
Collaborator

kostya commented Feb 17, 2020

After update to crystal-redid to 2.5.3
i got unexpected error in this code, for me this code looks ok:

redis = Redis.new
redis.keys("*").each { |key| redis.del(key) }
Showing last frame. Use --error-trace for full trace.

In src/redis/commands.cr:156:39

 156 | integer_command(concat(["DEL"], namespaced(keys)))
                                       ^---------
Error: no overload matches 'Redis#namespaced' with type Array(Redis::RedisValue)

Overloads are:
 - Redis::Commands#namespaced(keys : Array(String) | Tuple(String, String))
 - Redis::Commands#namespaced(key : String | Symbol | Int32)
stefanwille pushed a commit that referenced this issue Feb 20, 2020
stefanwille pushed a commit that referenced this issue Feb 20, 2020
@stefanwille
Copy link
Owner

The problem seems to be that #keys returns an Array(RedisValue), and #namespaced wants an Array(String). A possible fix is to allow the latter to accept an Array(RedisValue) instead and then convert to String.

A workaround would also be to perform the type cast yourself, as shown here:

https://github.com/stefanwille/crystal-redis/pull/101/files

@rodrigopinto
Copy link
Contributor

Hi @stefanwille, I was updating the lib on https://github.com/defense-cr/defense as it is a dependency and faced the same issue.

Debugging a bit the problem, I don't think the proposal workaround is a good way to proceed, neither the late suggestion of changing the method signature, but I explain below.

The method #keys is currently returning(Array(RedisValue)) an Array with the union type of RedisValue. By implementation redis keys are binary-safe strings, so, from my understanding, the keys will always be a string. Considering it, I believe Redis#keys("*") should return Array(String) instead of Array(RedisValue).

The current issue happens because of the private method without_namespace that cast all values to RedisValue as seen below.

# Returns all keys matching pattern.
#
# **Return value**: Array(String), array of keys matching pattern.
#
# Example:
#
# ```
# redis.keys("callmemaybe")
# ```
def keys(pattern)
string_array_command(["KEYS", namespaced(pattern)]).map { |key| without_namespace("#{key}") }
end

What do you think?

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 a pull request may close this issue.

3 participants