redis-namespace
代码来自redis-namespace-1.5.3/lib/redis/namespace.rb
它主要是通过method_missing来代理操作实际的redis client
def method_missing(command, *args, &block)
normalized_command = command.to_s.downcase
if ADMINISTRATIVE_COMMANDS.include?(normalized_command)
return super if deprecations?
call_with_namespace(command, *args, &block)
elsif COMMANDS.include?(normalized_command)
call_with_namespace(command, *args, &block)
elsif @redis.respond_to?(normalized_command) && !deprecations?
@redis.send(command, *args, &block)
else
super
end
end
def call_with_namespace(command, *args, &block)
handling = COMMANDS[command.to_s.downcase]
if handling.nil?
fail("Redis::Namespace does not know how to handle '#{command}'.")
end
(before, after) = handling
# Modify the local *args array in-place, no need to copy it.
args.map! {|arg| clone_args(arg)}
# Add the namespace to any parameters that are keys.
case before
when :first
args[0] = add_namespace(args[0]) if args[0]
when :all
args = add_namespace(args)
when :exclude_first
first = args.shift
args = add_namespace(args)
args.unshift(first) if first
when :exclude_last
last = args.pop unless args.length == 1
args = add_namespace(args)
args.push(last) if last
when :exclude_options
# ...
result = @redis.send(command, *args, &block)
# Don't try to remove namespace from a Redis::Future, you can't.
return result if result.is_a?(Redis::Future)
# Remove the namespace from results that are keys.
case after
when :all
result = rem_namespace(result)
when :first
result[0] = rem_namespace(result[0]) if result
when :second
result[1] = rem_namespace(result[1]) if result
end
result
end
而给“参数中的键”、“返回值中的键”添加namespace的规则如下
NAMESPACED_COMMANDS = {
"append" => [ :first ],
"bitcount" => [ :first ],
"bitop" => [ :exclude_first ],
"blpop" => [ :exclude_last, :first ],
"brpop" => [ :exclude_last, :first ],
"brpoplpush" => [ :exclude_last ],
"debug" => [ :exclude_first ],
"decr" => [ :first ],
# ...