Максимальная арность рубиновой функции?

Я ищу эффективную функцию для очистки кеша на основе Redis.

У меня есть вызов метода, который возвращает несколько ключей из Redis:

$redis.keys("foo:*")

Это возвращает все ключи, начинающиеся с «foo:». Далее я хотел бы удалить все значения для этих ключей.

Один (интенсивный по памяти) способ сделать это:

$redis.keys("foo:*").each do |key|
  $redis.del(key)
end

Я бы не хотел загружать все ключи в память, а затем делать многочисленные запросы к серверу Redis.

Другой способ, который мне нравится, — использовать оператор splat:

keys = $redis.keys("foo:*")
$redis.del(*keys)

Проблема в том, что я не знаю, какова максимальная арность метода $redis.del или любого метода ruby, я не могу найти его в Интернете.

Какая максимальная арность?


person tlehman    schedule 15.08.2013    source источник
comment
Я получаю SystemStackError: stack level too deep за более чем 130_000 аргументов на моей машине.   -  person Patrick Oscity    schedule 15.08.2013
comment
Мне то же. И иногда Ruby сильно падает: gist.github.com/DNNX/6243859   -  person DNNX    schedule 15.08.2013
comment
Вероятно, в реализации есть место для улучшения... В частности, когда был предоставлен только один аргумент splat, его можно было бы просто присвоить переменной args вместо того, чтобы делать какие-то рекурсивные вещи под капотом.   -  person Patrick Oscity    schedule 15.08.2013
comment
Возможно, драйвер Redis знает, что делать с аргументом массива? *keys будет массивом, когда он del все равно увидит его, поэтому, возможно, del достаточно умен, чтобы автоматически сгладить его (а если это не так, может быть, вы могли бы вставить в него какой-то смысл).   -  person mu is too short    schedule 15.08.2013
comment
И еще один интересный факт. Когда я не использую оператор splat, ruby ​​отлично работает, когда я определяю и вызываю функцию с 6892 аргументами, но терпит неудачу с ошибкой SO, если количество аргументов равно 6893. См. обновленную суть.   -  person DNNX    schedule 15.08.2013
comment
Я получаю SystemStackError, когда запускаю $redis.del(*$redis.keys("foo:*")) # => SystemStackError: stack level too deep, я посеял Redis с 1 000 000 ключей "foo:1", ... "foo:1000000". Это реалистичное количество ключей, один из способов сделать это — разбить ключи на куски по 1000 и разбить каждый из них. Достаточно ли низки накладные расходы, связанные с нарезкой рубиновых массивов, чтобы оно того стоило? Или я должен придерживаться моего первоначального решения?   -  person tlehman    schedule 16.08.2013
comment
@muistooshort оказывается, что драйвер Redis знает, что делать с аргументом массива, это сработало.   -  person tlehman    schedule 16.08.2013


Ответы (1)


У @muistooshort в комментариях было хорошее предложение, которое оказалось верным, драйвер Redis знает, что делать с аргументом массива:

 # there are 1,000,000 keys of the form "foo:#{number}"
 keys = $redis.keys("foo:*")
 $redis.del(keys) # => 1000000

Просто передайте массив ключей $redis.del

person tlehman    schedule 15.08.2013