redis 4.1.1 → 4.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/redis.rb CHANGED
@@ -4,13 +4,26 @@ require "monitor"
4
4
  require_relative "redis/errors"
5
5
 
6
6
  class Redis
7
+ class << self
8
+ attr_reader :exists_returns_integer
7
9
 
8
- def self.current
9
- @current ||= Redis.new
10
+ def exists_returns_integer=(value)
11
+ unless value
12
+ message = "`Redis#exists(key)` will return an Integer by default in redis-rb 4.3. The option to explicitly " \
13
+ "disable this behaviour via `Redis.exists_returns_integer` will be removed in 5.0. You should use " \
14
+ "`exists?` instead."
15
+
16
+ ::Kernel.warn(message)
17
+ end
18
+
19
+ @exists_returns_integer = value
20
+ end
21
+
22
+ attr_writer :current
10
23
  end
11
24
 
12
- def self.current=(redis)
13
- @current = redis
25
+ def self.current
26
+ @current ||= Redis.new
14
27
  end
15
28
 
16
29
  include MonitorMixin
@@ -18,18 +31,22 @@ class Redis
18
31
  # Create a new client instance
19
32
  #
20
33
  # @param [Hash] options
21
- # @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection: `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket connection: `unix://[path to Redis socket]`. This overrides all other options.
34
+ # @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection:
35
+ # `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket
36
+ # connection: `unix://[path to Redis socket]`. This overrides all other options.
22
37
  # @option options [String] :host ("127.0.0.1") server hostname
23
- # @option options [Fixnum] :port (6379) server port
38
+ # @option options [Integer] :port (6379) server port
24
39
  # @option options [String] :path path to server socket (overrides host and port)
25
40
  # @option options [Float] :timeout (5.0) timeout in seconds
26
41
  # @option options [Float] :connect_timeout (same as timeout) timeout for initial connect in seconds
27
42
  # @option options [String] :password Password to authenticate against server
28
- # @option options [Fixnum] :db (0) Database to select after initial connect
43
+ # @option options [Integer] :db (0) Database to select after initial connect
29
44
  # @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`, `:synchrony`
30
- # @option options [String] :id ID for the client connection, assigns name to current connection by sending `CLIENT SETNAME`
31
- # @option options [Hash, Fixnum] :tcp_keepalive Keepalive values, if Fixnum `intvl` and `probe` are calculated based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Fixnum
32
- # @option options [Fixnum] :reconnect_attempts Number of attempts trying to connect
45
+ # @option options [String] :id ID for the client connection, assigns name to current connection by sending
46
+ # `CLIENT SETNAME`
47
+ # @option options [Hash, Integer] :tcp_keepalive Keepalive values, if Integer `intvl` and `probe` are calculated
48
+ # based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer
49
+ # @option options [Integer] :reconnect_attempts Number of attempts trying to connect
33
50
  # @option options [Boolean] :inherit_socket (false) Whether to use socket in forked process or not
34
51
  # @option options [Array] :sentinels List of sentinels to contact
35
52
  # @option options [Symbol] :role (:master) Role to fetch via Sentinel, either `:master` or `:slave`
@@ -53,7 +70,7 @@ class Redis
53
70
  end
54
71
 
55
72
  # Run code with the client reconnecting
56
- def with_reconnect(val=true, &blk)
73
+ def with_reconnect(val = true, &blk)
57
74
  synchronize do |client|
58
75
  client.with_reconnect(val, &blk)
59
76
  end
@@ -96,7 +113,9 @@ class Redis
96
113
  # See http://redis.io/topics/pipelining for more details.
97
114
  #
98
115
  def queue(*command)
99
- @queue[Thread.current.object_id] << command
116
+ synchronize do
117
+ @queue[Thread.current.object_id] << command
118
+ end
100
119
  end
101
120
 
102
121
  # Sends all commands in the queue.
@@ -135,7 +154,7 @@ class Redis
135
154
 
136
155
  # Change the selected database for the current connection.
137
156
  #
138
- # @param [Fixnum] db zero-based index of the DB to use (0 to 15)
157
+ # @param [Integer] db zero-based index of the DB to use (0 to 15)
139
158
  # @return [String] `OK`
140
159
  def select(db)
141
160
  synchronize do |client|
@@ -204,7 +223,7 @@ class Redis
204
223
  def config(action, *args)
205
224
  synchronize do |client|
206
225
  client.call([:config, action] + args) do |reply|
207
- if reply.kind_of?(Array) && action == :get
226
+ if reply.is_a?(Array) && action == :get
208
227
  Hashify.call(reply)
209
228
  else
210
229
  reply
@@ -234,7 +253,7 @@ class Redis
234
253
 
235
254
  # Return the number of keys in the selected database.
236
255
  #
237
- # @return [Fixnum]
256
+ # @return [Integer]
238
257
  def dbsize
239
258
  synchronize do |client|
240
259
  client.call([:dbsize])
@@ -255,7 +274,7 @@ class Redis
255
274
  def flushall(options = nil)
256
275
  synchronize do |client|
257
276
  if options && options[:async]
258
- client.call([:flushall, :async])
277
+ client.call(%i[flushall async])
259
278
  else
260
279
  client.call([:flushall])
261
280
  end
@@ -270,7 +289,7 @@ class Redis
270
289
  def flushdb(options = nil)
271
290
  synchronize do |client|
272
291
  if options && options[:async]
273
- client.call([:flushdb, :async])
292
+ client.call(%i[flushdb async])
274
293
  else
275
294
  client.call([:flushdb])
276
295
  end
@@ -284,7 +303,7 @@ class Redis
284
303
  def info(cmd = nil)
285
304
  synchronize do |client|
286
305
  client.call([:info, cmd].compact) do |reply|
287
- if reply.kind_of?(String)
306
+ if reply.is_a?(String)
288
307
  reply = HashifyInfo.call(reply)
289
308
 
290
309
  if cmd && cmd.to_s == "commandstats"
@@ -303,7 +322,7 @@ class Redis
303
322
 
304
323
  # Get the UNIX time stamp of the last successful save to disk.
305
324
  #
306
- # @return [Fixnum]
325
+ # @return [Integer]
307
326
  def lastsave
308
327
  synchronize do |client|
309
328
  client.call([:lastsave])
@@ -355,9 +374,9 @@ class Redis
355
374
  # Interact with the slowlog (get, len, reset)
356
375
  #
357
376
  # @param [String] subcommand e.g. `get`, `len`, `reset`
358
- # @param [Fixnum] length maximum number of entries to return
359
- # @return [Array<String>, Fixnum, String] depends on subcommand
360
- def slowlog(subcommand, length=nil)
377
+ # @param [Integer] length maximum number of entries to return
378
+ # @return [Array<String>, Integer, String] depends on subcommand
379
+ def slowlog(subcommand, length = nil)
361
380
  synchronize do |client|
362
381
  args = [:slowlog, subcommand]
363
382
  args << length if length
@@ -377,12 +396,12 @@ class Redis
377
396
  # @example
378
397
  # r.time # => [ 1333093196, 606806 ]
379
398
  #
380
- # @return [Array<Fixnum>] tuple of seconds since UNIX epoch and
399
+ # @return [Array<Integer>] tuple of seconds since UNIX epoch and
381
400
  # microseconds in the current second
382
401
  def time
383
402
  synchronize do |client|
384
403
  client.call([:time]) do |reply|
385
- reply.map(&:to_i) if reply
404
+ reply&.map(&:to_i)
386
405
  end
387
406
  end
388
407
  end
@@ -400,7 +419,7 @@ class Redis
400
419
  # Set a key's time to live in seconds.
401
420
  #
402
421
  # @param [String] key
403
- # @param [Fixnum] seconds time to live
422
+ # @param [Integer] seconds time to live
404
423
  # @return [Boolean] whether the timeout was set or not
405
424
  def expire(key, seconds)
406
425
  synchronize do |client|
@@ -411,7 +430,7 @@ class Redis
411
430
  # Set the expiration for a key as a UNIX timestamp.
412
431
  #
413
432
  # @param [String] key
414
- # @param [Fixnum] unix_time expiry time specified as a UNIX timestamp
433
+ # @param [Integer] unix_time expiry time specified as a UNIX timestamp
415
434
  # @return [Boolean] whether the timeout was set or not
416
435
  def expireat(key, unix_time)
417
436
  synchronize do |client|
@@ -422,7 +441,7 @@ class Redis
422
441
  # Get the time to live (in seconds) for a key.
423
442
  #
424
443
  # @param [String] key
425
- # @return [Fixnum] remaining time to live in seconds.
444
+ # @return [Integer] remaining time to live in seconds.
426
445
  #
427
446
  # In Redis 2.6 or older the command returns -1 if the key does not exist or if
428
447
  # the key exist but has no associated expire.
@@ -440,7 +459,7 @@ class Redis
440
459
  # Set a key's time to live in milliseconds.
441
460
  #
442
461
  # @param [String] key
443
- # @param [Fixnum] milliseconds time to live
462
+ # @param [Integer] milliseconds time to live
444
463
  # @return [Boolean] whether the timeout was set or not
445
464
  def pexpire(key, milliseconds)
446
465
  synchronize do |client|
@@ -451,7 +470,7 @@ class Redis
451
470
  # Set the expiration for a key as number of milliseconds from UNIX Epoch.
452
471
  #
453
472
  # @param [String] key
454
- # @param [Fixnum] ms_unix_time expiry time specified as number of milliseconds from UNIX Epoch.
473
+ # @param [Integer] ms_unix_time expiry time specified as number of milliseconds from UNIX Epoch.
455
474
  # @return [Boolean] whether the timeout was set or not
456
475
  def pexpireat(key, ms_unix_time)
457
476
  synchronize do |client|
@@ -462,7 +481,7 @@ class Redis
462
481
  # Get the time to live (in milliseconds) for a key.
463
482
  #
464
483
  # @param [String] key
465
- # @return [Fixnum] remaining time to live in milliseconds
484
+ # @return [Integer] remaining time to live in milliseconds
466
485
  # In Redis 2.6 or older the command returns -1 if the key does not exist or if
467
486
  # the key exist but has no associated expire.
468
487
  #
@@ -495,9 +514,9 @@ class Redis
495
514
  # - `:replace => Boolean`: if false, raises an error if key already exists
496
515
  # @raise [Redis::CommandError]
497
516
  # @return [String] `"OK"`
498
- def restore(key, ttl, serialized_value, options = {})
517
+ def restore(key, ttl, serialized_value, replace: nil)
499
518
  args = [:restore, key, ttl, serialized_value]
500
- args << 'REPLACE' if options[:replace]
519
+ args << 'REPLACE' if replace
501
520
 
502
521
  synchronize do |client|
503
522
  client.call(args)
@@ -532,7 +551,7 @@ class Redis
532
551
  # Delete one or more keys.
533
552
  #
534
553
  # @param [String, Array<String>] keys
535
- # @return [Fixnum] number of keys that were deleted
554
+ # @return [Integer] number of keys that were deleted
536
555
  def del(*keys)
537
556
  synchronize do |client|
538
557
  client.call([:del] + keys)
@@ -542,20 +561,50 @@ class Redis
542
561
  # Unlink one or more keys.
543
562
  #
544
563
  # @param [String, Array<String>] keys
545
- # @return [Fixnum] number of keys that were unlinked
564
+ # @return [Integer] number of keys that were unlinked
546
565
  def unlink(*keys)
547
566
  synchronize do |client|
548
567
  client.call([:unlink] + keys)
549
568
  end
550
569
  end
551
570
 
552
- # Determine if a key exists.
571
+ # Determine how many of the keys exists.
553
572
  #
554
- # @param [String] key
573
+ # @param [String, Array<String>] keys
574
+ # @return [Integer]
575
+ def exists(*keys)
576
+ if !Redis.exists_returns_integer && keys.size == 1
577
+ if Redis.exists_returns_integer.nil?
578
+ message = "`Redis#exists(key)` will return an Integer in redis-rb 4.3. `exists?` returns a boolean, you " \
579
+ "should use it instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer = " \
580
+ "true. To disable this message and keep the current (boolean) behaviour of 'exists' you can set " \
581
+ "`Redis.exists_returns_integer = false`, but this option will be removed in 5.0. " \
582
+ "(#{::Kernel.caller(1, 1).first})\n"
583
+
584
+ ::Kernel.warn(message)
585
+ end
586
+
587
+ exists?(*keys)
588
+ else
589
+ _exists(*keys)
590
+ end
591
+ end
592
+
593
+ def _exists(*keys)
594
+ synchronize do |client|
595
+ client.call([:exists, *keys])
596
+ end
597
+ end
598
+
599
+ # Determine if any of the keys exists.
600
+ #
601
+ # @param [String, Array<String>] keys
555
602
  # @return [Boolean]
556
- def exists(key)
603
+ def exists?(*keys)
557
604
  synchronize do |client|
558
- client.call([:exists, key], &Boolify)
605
+ client.call([:exists, *keys]) do |value|
606
+ value > 0
607
+ end
559
608
  end
560
609
  end
561
610
 
@@ -566,7 +615,7 @@ class Redis
566
615
  def keys(pattern = "*")
567
616
  synchronize do |client|
568
617
  client.call([:keys, pattern]) do |reply|
569
- if reply.kind_of?(String)
618
+ if reply.is_a?(String)
570
619
  reply.split(" ")
571
620
  else
572
621
  reply
@@ -592,7 +641,7 @@ class Redis
592
641
  # # => "bar"
593
642
  #
594
643
  # @param [String] key
595
- # @param [Fixnum] db
644
+ # @param [Integer] db
596
645
  # @return [Boolean] whether the key was moved or not
597
646
  def move(key, db)
598
647
  synchronize do |client|
@@ -656,36 +705,33 @@ class Redis
656
705
  # - `:order => String`: combination of `ASC`, `DESC` and optionally `ALPHA`
657
706
  # - `:store => String`: key to store the result at
658
707
  #
659
- # @return [Array<String>, Array<Array<String>>, Fixnum]
708
+ # @return [Array<String>, Array<Array<String>>, Integer]
660
709
  # - when `:get` is not specified, or holds a single element, an array of elements
661
710
  # - when `:get` is specified, and holds more than one element, an array of
662
711
  # elements where every element is an array with the result for every
663
712
  # element specified in `:get`
664
713
  # - when `:store` is specified, the number of elements in the stored result
665
- def sort(key, options = {})
666
- args = []
667
-
668
- by = options[:by]
669
- args.concat(["BY", by]) if by
714
+ def sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil)
715
+ args = [:sort, key]
716
+ args << "BY" << by if by
670
717
 
671
- limit = options[:limit]
672
- args.concat(["LIMIT"] + limit) if limit
718
+ if limit
719
+ args << "LIMIT"
720
+ args.concat(limit)
721
+ end
673
722
 
674
- get = Array(options[:get])
675
- args.concat(["GET"].product(get).flatten) unless get.empty?
723
+ get = Array(get)
724
+ get.each do |item|
725
+ args << "GET" << item
726
+ end
676
727
 
677
- order = options[:order]
678
728
  args.concat(order.split(" ")) if order
679
-
680
- store = options[:store]
681
- args.concat(["STORE", store]) if store
729
+ args << "STORE" << store if store
682
730
 
683
731
  synchronize do |client|
684
- client.call([:sort, key] + args) do |reply|
732
+ client.call(args) do |reply|
685
733
  if get.size > 1 && !store
686
- if reply
687
- reply.each_slice(get.size).to_a
688
- end
734
+ reply.each_slice(get.size).to_a if reply
689
735
  else
690
736
  reply
691
737
  end
@@ -710,7 +756,7 @@ class Redis
710
756
  # # => 4
711
757
  #
712
758
  # @param [String] key
713
- # @return [Fixnum] value after decrementing it
759
+ # @return [Integer] value after decrementing it
714
760
  def decr(key)
715
761
  synchronize do |client|
716
762
  client.call([:decr, key])
@@ -724,8 +770,8 @@ class Redis
724
770
  # # => 0
725
771
  #
726
772
  # @param [String] key
727
- # @param [Fixnum] decrement
728
- # @return [Fixnum] value after decrementing it
773
+ # @param [Integer] decrement
774
+ # @return [Integer] value after decrementing it
729
775
  def decrby(key, decrement)
730
776
  synchronize do |client|
731
777
  client.call([:decrby, key, decrement])
@@ -739,7 +785,7 @@ class Redis
739
785
  # # => 6
740
786
  #
741
787
  # @param [String] key
742
- # @return [Fixnum] value after incrementing it
788
+ # @return [Integer] value after incrementing it
743
789
  def incr(key)
744
790
  synchronize do |client|
745
791
  client.call([:incr, key])
@@ -753,8 +799,8 @@ class Redis
753
799
  # # => 10
754
800
  #
755
801
  # @param [String] key
756
- # @param [Fixnum] increment
757
- # @return [Fixnum] value after incrementing it
802
+ # @param [Integer] increment
803
+ # @return [Integer] value after incrementing it
758
804
  def incrby(key, increment)
759
805
  synchronize do |client|
760
806
  client.call([:incrby, key, increment])
@@ -781,31 +827,25 @@ class Redis
781
827
  # @param [String] key
782
828
  # @param [String] value
783
829
  # @param [Hash] options
784
- # - `:ex => Fixnum`: Set the specified expire time, in seconds.
785
- # - `:px => Fixnum`: Set the specified expire time, in milliseconds.
830
+ # - `:ex => Integer`: Set the specified expire time, in seconds.
831
+ # - `:px => Integer`: Set the specified expire time, in milliseconds.
786
832
  # - `:nx => true`: Only set the key if it does not already exist.
787
833
  # - `:xx => true`: Only set the key if it already exist.
834
+ # - `:keepttl => true`: Retain the time to live associated with the key.
788
835
  # @return [String, Boolean] `"OK"` or true, false if `:nx => true` or `:xx => true`
789
- def set(key, value, options = {})
790
- args = []
791
-
792
- ex = options[:ex]
793
- args.concat(["EX", ex]) if ex
794
-
795
- px = options[:px]
796
- args.concat(["PX", px]) if px
797
-
798
- nx = options[:nx]
799
- args.concat(["NX"]) if nx
800
-
801
- xx = options[:xx]
802
- args.concat(["XX"]) if xx
836
+ def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil)
837
+ args = [:set, key, value.to_s]
838
+ args << "EX" << ex if ex
839
+ args << "PX" << px if px
840
+ args << "NX" if nx
841
+ args << "XX" if xx
842
+ args << "KEEPTTL" if keepttl
803
843
 
804
844
  synchronize do |client|
805
845
  if nx || xx
806
- client.call([:set, key, value.to_s] + args, &BoolifySet)
846
+ client.call(args, &BoolifySet)
807
847
  else
808
- client.call([:set, key, value.to_s] + args)
848
+ client.call(args)
809
849
  end
810
850
  end
811
851
  end
@@ -813,7 +853,7 @@ class Redis
813
853
  # Set the time to live in seconds of a key.
814
854
  #
815
855
  # @param [String] key
816
- # @param [Fixnum] ttl
856
+ # @param [Integer] ttl
817
857
  # @param [String] value
818
858
  # @return [String] `"OK"`
819
859
  def setex(key, ttl, value)
@@ -825,7 +865,7 @@ class Redis
825
865
  # Set the time to live in milliseconds of a key.
826
866
  #
827
867
  # @param [String] key
828
- # @param [Fixnum] ttl
868
+ # @param [Integer] ttl
829
869
  # @param [String] value
830
870
  # @return [String] `"OK"`
831
871
  def psetex(key, ttl, value)
@@ -887,7 +927,7 @@ class Redis
887
927
  # @see #mapped_msetnx
888
928
  def msetnx(*args)
889
929
  synchronize do |client|
890
- client.call([:msetnx] + args, &Boolify)
930
+ client.call([:msetnx, *args], &Boolify)
891
931
  end
892
932
  end
893
933
 
@@ -918,7 +958,7 @@ class Redis
918
958
  # Get the values of all the given keys.
919
959
  #
920
960
  # @example
921
- # redis.mget("key1", "key1")
961
+ # redis.mget("key1", "key2")
922
962
  # # => ["v1", "v2"]
923
963
  #
924
964
  # @param [Array<String>] keys
@@ -927,7 +967,7 @@ class Redis
927
967
  # @see #mapped_mget
928
968
  def mget(*keys, &blk)
929
969
  synchronize do |client|
930
- client.call([:mget] + keys, &blk)
970
+ client.call([:mget, *keys], &blk)
931
971
  end
932
972
  end
933
973
 
@@ -943,7 +983,7 @@ class Redis
943
983
  # @see #mget
944
984
  def mapped_mget(*keys)
945
985
  mget(*keys) do |reply|
946
- if reply.kind_of?(Array)
986
+ if reply.is_a?(Array)
947
987
  Hash[keys.zip(reply)]
948
988
  else
949
989
  reply
@@ -954,9 +994,9 @@ class Redis
954
994
  # Overwrite part of a string at key starting at the specified offset.
955
995
  #
956
996
  # @param [String] key
957
- # @param [Fixnum] offset byte offset
997
+ # @param [Integer] offset byte offset
958
998
  # @param [String] value
959
- # @return [Fixnum] length of the string after it was modified
999
+ # @return [Integer] length of the string after it was modified
960
1000
  def setrange(key, offset, value)
961
1001
  synchronize do |client|
962
1002
  client.call([:setrange, key, offset, value.to_s])
@@ -966,10 +1006,10 @@ class Redis
966
1006
  # Get a substring of the string stored at a key.
967
1007
  #
968
1008
  # @param [String] key
969
- # @param [Fixnum] start zero-based start offset
970
- # @param [Fixnum] stop zero-based end offset. Use -1 for representing
1009
+ # @param [Integer] start zero-based start offset
1010
+ # @param [Integer] stop zero-based end offset. Use -1 for representing
971
1011
  # the end of the string
972
- # @return [Fixnum] `0` or `1`
1012
+ # @return [Integer] `0` or `1`
973
1013
  def getrange(key, start, stop)
974
1014
  synchronize do |client|
975
1015
  client.call([:getrange, key, start, stop])
@@ -979,9 +1019,9 @@ class Redis
979
1019
  # Sets or clears the bit at offset in the string value stored at key.
980
1020
  #
981
1021
  # @param [String] key
982
- # @param [Fixnum] offset bit offset
983
- # @param [Fixnum] value bit value `0` or `1`
984
- # @return [Fixnum] the original bit value stored at `offset`
1022
+ # @param [Integer] offset bit offset
1023
+ # @param [Integer] value bit value `0` or `1`
1024
+ # @return [Integer] the original bit value stored at `offset`
985
1025
  def setbit(key, offset, value)
986
1026
  synchronize do |client|
987
1027
  client.call([:setbit, key, offset, value])
@@ -991,8 +1031,8 @@ class Redis
991
1031
  # Returns the bit value at offset in the string value stored at key.
992
1032
  #
993
1033
  # @param [String] key
994
- # @param [Fixnum] offset bit offset
995
- # @return [Fixnum] `0` or `1`
1034
+ # @param [Integer] offset bit offset
1035
+ # @return [Integer] `0` or `1`
996
1036
  def getbit(key, offset)
997
1037
  synchronize do |client|
998
1038
  client.call([:getbit, key, offset])
@@ -1003,7 +1043,7 @@ class Redis
1003
1043
  #
1004
1044
  # @param [String] key
1005
1045
  # @param [String] value value to append
1006
- # @return [Fixnum] length of the string after appending
1046
+ # @return [Integer] length of the string after appending
1007
1047
  def append(key, value)
1008
1048
  synchronize do |client|
1009
1049
  client.call([:append, key, value])
@@ -1013,9 +1053,9 @@ class Redis
1013
1053
  # Count the number of set bits in a range of the string value stored at key.
1014
1054
  #
1015
1055
  # @param [String] key
1016
- # @param [Fixnum] start start index
1017
- # @param [Fixnum] stop stop index
1018
- # @return [Fixnum] the number of bits set to 1
1056
+ # @param [Integer] start start index
1057
+ # @param [Integer] stop stop index
1058
+ # @return [Integer] the number of bits set to 1
1019
1059
  def bitcount(key, start = 0, stop = -1)
1020
1060
  synchronize do |client|
1021
1061
  client.call([:bitcount, key, start, stop])
@@ -1027,25 +1067,23 @@ class Redis
1027
1067
  # @param [String] operation e.g. `and`, `or`, `xor`, `not`
1028
1068
  # @param [String] destkey destination key
1029
1069
  # @param [String, Array<String>] keys one or more source keys to perform `operation`
1030
- # @return [Fixnum] the length of the string stored in `destkey`
1070
+ # @return [Integer] the length of the string stored in `destkey`
1031
1071
  def bitop(operation, destkey, *keys)
1032
1072
  synchronize do |client|
1033
- client.call([:bitop, operation, destkey] + keys)
1073
+ client.call([:bitop, operation, destkey, *keys])
1034
1074
  end
1035
1075
  end
1036
1076
 
1037
1077
  # Return the position of the first bit set to 1 or 0 in a string.
1038
1078
  #
1039
1079
  # @param [String] key
1040
- # @param [Fixnum] bit whether to look for the first 1 or 0 bit
1041
- # @param [Fixnum] start start index
1042
- # @param [Fixnum] stop stop index
1043
- # @return [Fixnum] the position of the first 1/0 bit.
1080
+ # @param [Integer] bit whether to look for the first 1 or 0 bit
1081
+ # @param [Integer] start start index
1082
+ # @param [Integer] stop stop index
1083
+ # @return [Integer] the position of the first 1/0 bit.
1044
1084
  # -1 if looking for 1 and it is not found or start and stop are given.
1045
- def bitpos(key, bit, start=nil, stop=nil)
1046
- if stop and not start
1047
- raise(ArgumentError, 'stop parameter specified without start parameter')
1048
- end
1085
+ def bitpos(key, bit, start = nil, stop = nil)
1086
+ raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
1049
1087
 
1050
1088
  synchronize do |client|
1051
1089
  command = [:bitpos, key, bit]
@@ -1070,7 +1108,7 @@ class Redis
1070
1108
  # Get the length of the value stored in a key.
1071
1109
  #
1072
1110
  # @param [String] key
1073
- # @return [Fixnum] the length of the value stored in the key, or 0
1111
+ # @return [Integer] the length of the value stored in the key, or 0
1074
1112
  # if the key does not exist
1075
1113
  def strlen(key)
1076
1114
  synchronize do |client|
@@ -1081,7 +1119,7 @@ class Redis
1081
1119
  # Get the length of a list.
1082
1120
  #
1083
1121
  # @param [String] key
1084
- # @return [Fixnum]
1122
+ # @return [Integer]
1085
1123
  def llen(key)
1086
1124
  synchronize do |client|
1087
1125
  client.call([:llen, key])
@@ -1092,7 +1130,7 @@ class Redis
1092
1130
  #
1093
1131
  # @param [String] key
1094
1132
  # @param [String, Array<String>] value string value, or array of string values to push
1095
- # @return [Fixnum] the length of the list after the push operation
1133
+ # @return [Integer] the length of the list after the push operation
1096
1134
  def lpush(key, value)
1097
1135
  synchronize do |client|
1098
1136
  client.call([:lpush, key, value])
@@ -1103,7 +1141,7 @@ class Redis
1103
1141
  #
1104
1142
  # @param [String] key
1105
1143
  # @param [String] value
1106
- # @return [Fixnum] the length of the list after the push operation
1144
+ # @return [Integer] the length of the list after the push operation
1107
1145
  def lpushx(key, value)
1108
1146
  synchronize do |client|
1109
1147
  client.call([:lpushx, key, value])
@@ -1114,7 +1152,7 @@ class Redis
1114
1152
  #
1115
1153
  # @param [String] key
1116
1154
  # @param [String, Array<String>] value string value, or array of string values to push
1117
- # @return [Fixnum] the length of the list after the push operation
1155
+ # @return [Integer] the length of the list after the push operation
1118
1156
  def rpush(key, value)
1119
1157
  synchronize do |client|
1120
1158
  client.call([:rpush, key, value])
@@ -1125,7 +1163,7 @@ class Redis
1125
1163
  #
1126
1164
  # @param [String] key
1127
1165
  # @param [String] value
1128
- # @return [Fixnum] the length of the list after the push operation
1166
+ # @return [Integer] the length of the list after the push operation
1129
1167
  def rpushx(key, value)
1130
1168
  synchronize do |client|
1131
1169
  client.call([:rpushx, key, value])
@@ -1164,21 +1202,21 @@ class Redis
1164
1202
  end
1165
1203
 
1166
1204
  def _bpop(cmd, args, &blk)
1167
- options = {}
1168
-
1169
- if args.last.is_a?(Hash)
1205
+ timeout = if args.last.is_a?(Hash)
1170
1206
  options = args.pop
1207
+ options[:timeout]
1171
1208
  elsif args.last.respond_to?(:to_int)
1172
1209
  # Issue deprecation notice in obnoxious mode...
1173
- options[:timeout] = args.pop.to_int
1210
+ args.pop.to_int
1174
1211
  end
1175
1212
 
1213
+ timeout ||= 0
1214
+
1176
1215
  if args.size > 1
1177
1216
  # Issue deprecation notice in obnoxious mode...
1178
1217
  end
1179
1218
 
1180
1219
  keys = args.flatten
1181
- timeout = options[:timeout] || 0
1182
1220
 
1183
1221
  synchronize do |client|
1184
1222
  command = [cmd, keys, timeout]
@@ -1203,7 +1241,7 @@ class Redis
1203
1241
  # @param [String, Array<String>] keys one or more keys to perform the
1204
1242
  # blocking pop on
1205
1243
  # @param [Hash] options
1206
- # - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
1244
+ # - `:timeout => Integer`: timeout in seconds, defaults to no timeout
1207
1245
  #
1208
1246
  # @return [nil, [String, String]]
1209
1247
  # - `nil` when the operation timed out
@@ -1217,7 +1255,7 @@ class Redis
1217
1255
  # @param [String, Array<String>] keys one or more keys to perform the
1218
1256
  # blocking pop on
1219
1257
  # @param [Hash] options
1220
- # - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
1258
+ # - `:timeout => Integer`: timeout in seconds, defaults to no timeout
1221
1259
  #
1222
1260
  # @return [nil, [String, String]]
1223
1261
  # - `nil` when the operation timed out
@@ -1234,20 +1272,12 @@ class Redis
1234
1272
  # @param [String] source source key
1235
1273
  # @param [String] destination destination key
1236
1274
  # @param [Hash] options
1237
- # - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
1275
+ # - `:timeout => Integer`: timeout in seconds, defaults to no timeout
1238
1276
  #
1239
1277
  # @return [nil, String]
1240
1278
  # - `nil` when the operation timed out
1241
1279
  # - the element was popped and pushed otherwise
1242
- def brpoplpush(source, destination, options = {})
1243
- case options
1244
- when Integer
1245
- # Issue deprecation notice in obnoxious mode...
1246
- options = { :timeout => options }
1247
- end
1248
-
1249
- timeout = options[:timeout] || 0
1250
-
1280
+ def brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout)
1251
1281
  synchronize do |client|
1252
1282
  command = [:brpoplpush, source, destination, timeout]
1253
1283
  timeout += client.timeout if timeout > 0
@@ -1258,7 +1288,7 @@ class Redis
1258
1288
  # Get an element from a list by its index.
1259
1289
  #
1260
1290
  # @param [String] key
1261
- # @param [Fixnum] index
1291
+ # @param [Integer] index
1262
1292
  # @return [String]
1263
1293
  def lindex(key, index)
1264
1294
  synchronize do |client|
@@ -1272,7 +1302,7 @@ class Redis
1272
1302
  # @param [String, Symbol] where `BEFORE` or `AFTER`
1273
1303
  # @param [String] pivot reference element
1274
1304
  # @param [String] value
1275
- # @return [Fixnum] length of the list after the insert operation, or `-1`
1305
+ # @return [Integer] length of the list after the insert operation, or `-1`
1276
1306
  # when the element `pivot` was not found
1277
1307
  def linsert(key, where, pivot, value)
1278
1308
  synchronize do |client|
@@ -1283,8 +1313,8 @@ class Redis
1283
1313
  # Get a range of elements from a list.
1284
1314
  #
1285
1315
  # @param [String] key
1286
- # @param [Fixnum] start start index
1287
- # @param [Fixnum] stop stop index
1316
+ # @param [Integer] start start index
1317
+ # @param [Integer] stop stop index
1288
1318
  # @return [Array<String>]
1289
1319
  def lrange(key, start, stop)
1290
1320
  synchronize do |client|
@@ -1295,12 +1325,12 @@ class Redis
1295
1325
  # Remove elements from a list.
1296
1326
  #
1297
1327
  # @param [String] key
1298
- # @param [Fixnum] count number of elements to remove. Use a positive
1328
+ # @param [Integer] count number of elements to remove. Use a positive
1299
1329
  # value to remove the first `count` occurrences of `value`. A negative
1300
1330
  # value to remove the last `count` occurrences of `value`. Or zero, to
1301
1331
  # remove all occurrences of `value` from the list.
1302
1332
  # @param [String] value
1303
- # @return [Fixnum] the number of removed elements
1333
+ # @return [Integer] the number of removed elements
1304
1334
  def lrem(key, count, value)
1305
1335
  synchronize do |client|
1306
1336
  client.call([:lrem, key, count, value])
@@ -1310,7 +1340,7 @@ class Redis
1310
1340
  # Set the value of an element in a list by its index.
1311
1341
  #
1312
1342
  # @param [String] key
1313
- # @param [Fixnum] index
1343
+ # @param [Integer] index
1314
1344
  # @param [String] value
1315
1345
  # @return [String] `OK`
1316
1346
  def lset(key, index, value)
@@ -1322,8 +1352,8 @@ class Redis
1322
1352
  # Trim a list to the specified range.
1323
1353
  #
1324
1354
  # @param [String] key
1325
- # @param [Fixnum] start start index
1326
- # @param [Fixnum] stop stop index
1355
+ # @param [Integer] start start index
1356
+ # @param [Integer] stop stop index
1327
1357
  # @return [String] `OK`
1328
1358
  def ltrim(key, start, stop)
1329
1359
  synchronize do |client|
@@ -1334,7 +1364,7 @@ class Redis
1334
1364
  # Get the number of members in a set.
1335
1365
  #
1336
1366
  # @param [String] key
1337
- # @return [Fixnum]
1367
+ # @return [Integer]
1338
1368
  def scard(key)
1339
1369
  synchronize do |client|
1340
1370
  client.call([:scard, key])
@@ -1345,8 +1375,8 @@ class Redis
1345
1375
  #
1346
1376
  # @param [String] key
1347
1377
  # @param [String, Array<String>] member one member, or array of members
1348
- # @return [Boolean, Fixnum] `Boolean` when a single member is specified,
1349
- # holding whether or not adding the member succeeded, or `Fixnum` when an
1378
+ # @return [Boolean, Integer] `Boolean` when a single member is specified,
1379
+ # holding whether or not adding the member succeeded, or `Integer` when an
1350
1380
  # array of members is specified, holding the number of members that were
1351
1381
  # successfully added
1352
1382
  def sadd(key, member)
@@ -1367,8 +1397,8 @@ class Redis
1367
1397
  #
1368
1398
  # @param [String] key
1369
1399
  # @param [String, Array<String>] member one member, or array of members
1370
- # @return [Boolean, Fixnum] `Boolean` when a single member is specified,
1371
- # holding whether or not removing the member succeeded, or `Fixnum` when an
1400
+ # @return [Boolean, Integer] `Boolean` when a single member is specified,
1401
+ # holding whether or not removing the member succeeded, or `Integer` when an
1372
1402
  # array of members is specified, holding the number of members that were
1373
1403
  # successfully removed
1374
1404
  def srem(key, member)
@@ -1389,7 +1419,7 @@ class Redis
1389
1419
  #
1390
1420
  # @param [String] key
1391
1421
  # @return [String]
1392
- # @param [Fixnum] count
1422
+ # @param [Integer] count
1393
1423
  def spop(key, count = nil)
1394
1424
  synchronize do |client|
1395
1425
  if count.nil?
@@ -1403,7 +1433,7 @@ class Redis
1403
1433
  # Get one or more random members from a set.
1404
1434
  #
1405
1435
  # @param [String] key
1406
- # @param [Fixnum] count
1436
+ # @param [Integer] count
1407
1437
  # @return [String]
1408
1438
  def srandmember(key, count = nil)
1409
1439
  synchronize do |client|
@@ -1454,7 +1484,7 @@ class Redis
1454
1484
  # @return [Array<String>] members in the difference
1455
1485
  def sdiff(*keys)
1456
1486
  synchronize do |client|
1457
- client.call([:sdiff] + keys)
1487
+ client.call([:sdiff, *keys])
1458
1488
  end
1459
1489
  end
1460
1490
 
@@ -1462,10 +1492,10 @@ class Redis
1462
1492
  #
1463
1493
  # @param [String] destination destination key
1464
1494
  # @param [String, Array<String>] keys keys pointing to sets to subtract
1465
- # @return [Fixnum] number of elements in the resulting set
1495
+ # @return [Integer] number of elements in the resulting set
1466
1496
  def sdiffstore(destination, *keys)
1467
1497
  synchronize do |client|
1468
- client.call([:sdiffstore, destination] + keys)
1498
+ client.call([:sdiffstore, destination, *keys])
1469
1499
  end
1470
1500
  end
1471
1501
 
@@ -1475,7 +1505,7 @@ class Redis
1475
1505
  # @return [Array<String>] members in the intersection
1476
1506
  def sinter(*keys)
1477
1507
  synchronize do |client|
1478
- client.call([:sinter] + keys)
1508
+ client.call([:sinter, *keys])
1479
1509
  end
1480
1510
  end
1481
1511
 
@@ -1483,10 +1513,10 @@ class Redis
1483
1513
  #
1484
1514
  # @param [String] destination destination key
1485
1515
  # @param [String, Array<String>] keys keys pointing to sets to intersect
1486
- # @return [Fixnum] number of elements in the resulting set
1516
+ # @return [Integer] number of elements in the resulting set
1487
1517
  def sinterstore(destination, *keys)
1488
1518
  synchronize do |client|
1489
- client.call([:sinterstore, destination] + keys)
1519
+ client.call([:sinterstore, destination, *keys])
1490
1520
  end
1491
1521
  end
1492
1522
 
@@ -1496,7 +1526,7 @@ class Redis
1496
1526
  # @return [Array<String>] members in the union
1497
1527
  def sunion(*keys)
1498
1528
  synchronize do |client|
1499
- client.call([:sunion] + keys)
1529
+ client.call([:sunion, *keys])
1500
1530
  end
1501
1531
  end
1502
1532
 
@@ -1504,10 +1534,10 @@ class Redis
1504
1534
  #
1505
1535
  # @param [String] destination destination key
1506
1536
  # @param [String, Array<String>] keys keys pointing to sets to unify
1507
- # @return [Fixnum] number of elements in the resulting set
1537
+ # @return [Integer] number of elements in the resulting set
1508
1538
  def sunionstore(destination, *keys)
1509
1539
  synchronize do |client|
1510
- client.call([:sunionstore, destination] + keys)
1540
+ client.call([:sunionstore, destination, *keys])
1511
1541
  end
1512
1542
  end
1513
1543
 
@@ -1518,7 +1548,7 @@ class Redis
1518
1548
  # # => 4
1519
1549
  #
1520
1550
  # @param [String] key
1521
- # @return [Fixnum]
1551
+ # @return [Integer]
1522
1552
  def zcard(key)
1523
1553
  synchronize do |client|
1524
1554
  client.call([:zcard, key])
@@ -1549,38 +1579,27 @@ class Redis
1549
1579
  # - `:incr => true`: When this option is specified ZADD acts like
1550
1580
  # ZINCRBY; only one score-element pair can be specified in this mode
1551
1581
  #
1552
- # @return [Boolean, Fixnum, Float]
1582
+ # @return [Boolean, Integer, Float]
1553
1583
  # - `Boolean` when a single pair is specified, holding whether or not it was
1554
1584
  # **added** to the sorted set.
1555
- # - `Fixnum` when an array of pairs is specified, holding the number of
1585
+ # - `Integer` when an array of pairs is specified, holding the number of
1556
1586
  # pairs that were **added** to the sorted set.
1557
1587
  # - `Float` when option :incr is specified, holding the score of the member
1558
1588
  # after incrementing it.
1559
- def zadd(key, *args) #, options
1560
- zadd_options = []
1561
- if args.last.is_a?(Hash)
1562
- options = args.pop
1563
-
1564
- nx = options[:nx]
1565
- zadd_options << "NX" if nx
1566
-
1567
- xx = options[:xx]
1568
- zadd_options << "XX" if xx
1569
-
1570
- ch = options[:ch]
1571
- zadd_options << "CH" if ch
1572
-
1573
- incr = options[:incr]
1574
- zadd_options << "INCR" if incr
1575
- end
1589
+ def zadd(key, *args, nx: nil, xx: nil, ch: nil, incr: nil)
1590
+ command = [:zadd, key]
1591
+ command << "NX" if nx
1592
+ command << "XX" if xx
1593
+ command << "CH" if ch
1594
+ command << "INCR" if incr
1576
1595
 
1577
1596
  synchronize do |client|
1578
1597
  if args.size == 1 && args[0].is_a?(Array)
1579
1598
  # Variadic: return float if INCR, integer if !INCR
1580
- client.call([:zadd, key] + zadd_options + args[0], &(incr ? Floatify : nil))
1599
+ client.call(command + args[0], &(incr ? Floatify : nil))
1581
1600
  elsif args.size == 2
1582
1601
  # Single pair: return float if INCR, boolean if !INCR
1583
- client.call([:zadd, key] + zadd_options + args, &(incr ? Floatify : Boolify))
1602
+ client.call(command + args, &(incr ? Floatify : Boolify))
1584
1603
  else
1585
1604
  raise ArgumentError, "wrong number of arguments"
1586
1605
  end
@@ -1615,10 +1634,10 @@ class Redis
1615
1634
  # - a single member
1616
1635
  # - an array of members
1617
1636
  #
1618
- # @return [Boolean, Fixnum]
1637
+ # @return [Boolean, Integer]
1619
1638
  # - `Boolean` when a single member is specified, holding whether or not it
1620
1639
  # was removed from the sorted set
1621
- # - `Fixnum` when an array of pairs is specified, holding the number of
1640
+ # - `Integer` when an array of pairs is specified, holding the number of
1622
1641
  # members that were removed to the sorted set
1623
1642
  def zrem(key, member)
1624
1643
  synchronize do |client|
@@ -1743,18 +1762,16 @@ class Redis
1743
1762
  # # => [["a", 32.0], ["b", 64.0]]
1744
1763
  #
1745
1764
  # @param [String] key
1746
- # @param [Fixnum] start start index
1747
- # @param [Fixnum] stop stop index
1765
+ # @param [Integer] start start index
1766
+ # @param [Integer] stop stop index
1748
1767
  # @param [Hash] options
1749
1768
  # - `:with_scores => true`: include scores in output
1750
1769
  #
1751
1770
  # @return [Array<String>, Array<[String, Float]>]
1752
1771
  # - when `:with_scores` is not specified, an array of members
1753
1772
  # - when `:with_scores` is specified, an array with `[member, score]` pairs
1754
- def zrange(key, start, stop, options = {})
1755
- args = []
1756
-
1757
- with_scores = options[:with_scores] || options[:withscores]
1773
+ def zrange(key, start, stop, withscores: false, with_scores: withscores)
1774
+ args = [:zrange, key, start, stop]
1758
1775
 
1759
1776
  if with_scores
1760
1777
  args << "WITHSCORES"
@@ -1762,7 +1779,7 @@ class Redis
1762
1779
  end
1763
1780
 
1764
1781
  synchronize do |client|
1765
- client.call([:zrange, key, start, stop] + args, &block)
1782
+ client.call(args, &block)
1766
1783
  end
1767
1784
  end
1768
1785
 
@@ -1777,10 +1794,8 @@ class Redis
1777
1794
  # # => [["b", 64.0], ["a", 32.0]]
1778
1795
  #
1779
1796
  # @see #zrange
1780
- def zrevrange(key, start, stop, options = {})
1781
- args = []
1782
-
1783
- with_scores = options[:with_scores] || options[:withscores]
1797
+ def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
1798
+ args = [:zrevrange, key, start, stop]
1784
1799
 
1785
1800
  if with_scores
1786
1801
  args << "WITHSCORES"
@@ -1788,7 +1803,7 @@ class Redis
1788
1803
  end
1789
1804
 
1790
1805
  synchronize do |client|
1791
- client.call([:zrevrange, key, start, stop] + args, &block)
1806
+ client.call(args, &block)
1792
1807
  end
1793
1808
  end
1794
1809
 
@@ -1796,7 +1811,7 @@ class Redis
1796
1811
  #
1797
1812
  # @param [String] key
1798
1813
  # @param [String] member
1799
- # @return [Fixnum]
1814
+ # @return [Integer]
1800
1815
  def zrank(key, member)
1801
1816
  synchronize do |client|
1802
1817
  client.call([:zrank, key, member])
@@ -1808,7 +1823,7 @@ class Redis
1808
1823
  #
1809
1824
  # @param [String] key
1810
1825
  # @param [String] member
1811
- # @return [Fixnum]
1826
+ # @return [Integer]
1812
1827
  def zrevrank(key, member)
1813
1828
  synchronize do |client|
1814
1829
  client.call([:zrevrank, key, member])
@@ -1825,9 +1840,9 @@ class Redis
1825
1840
  # # => 5
1826
1841
  #
1827
1842
  # @param [String] key
1828
- # @param [Fixnum] start start index
1829
- # @param [Fixnum] stop stop index
1830
- # @return [Fixnum] number of members that were removed
1843
+ # @param [Integer] start start index
1844
+ # @param [Integer] stop stop index
1845
+ # @return [Integer] number of members that were removed
1831
1846
  def zremrangebyrank(key, start, stop)
1832
1847
  synchronize do |client|
1833
1848
  client.call([:zremrangebyrank, key, start, stop])
@@ -1851,7 +1866,7 @@ class Redis
1851
1866
  # - inclusive maximum is specified by prefixing `(`
1852
1867
  # - exclusive maximum is specified by prefixing `[`
1853
1868
  #
1854
- # @return [Fixnum] number of members within the specified lexicographical range
1869
+ # @return [Integer] number of members within the specified lexicographical range
1855
1870
  def zlexcount(key, min, max)
1856
1871
  synchronize do |client|
1857
1872
  client.call([:zlexcount, key, min, max])
@@ -1879,14 +1894,16 @@ class Redis
1879
1894
  # `count` members
1880
1895
  #
1881
1896
  # @return [Array<String>, Array<[String, Float]>]
1882
- def zrangebylex(key, min, max, options = {})
1883
- args = []
1897
+ def zrangebylex(key, min, max, limit: nil)
1898
+ args = [:zrangebylex, key, min, max]
1884
1899
 
1885
- limit = options[:limit]
1886
- args.concat(["LIMIT"] + limit) if limit
1900
+ if limit
1901
+ args << "LIMIT"
1902
+ args.concat(limit)
1903
+ end
1887
1904
 
1888
1905
  synchronize do |client|
1889
- client.call([:zrangebylex, key, min, max] + args)
1906
+ client.call(args)
1890
1907
  end
1891
1908
  end
1892
1909
 
@@ -1901,14 +1918,16 @@ class Redis
1901
1918
  # # => ["abbygail", "abby"]
1902
1919
  #
1903
1920
  # @see #zrangebylex
1904
- def zrevrangebylex(key, max, min, options = {})
1905
- args = []
1921
+ def zrevrangebylex(key, max, min, limit: nil)
1922
+ args = [:zrevrangebylex, key, max, min]
1906
1923
 
1907
- limit = options[:limit]
1908
- args.concat(["LIMIT"] + limit) if limit
1924
+ if limit
1925
+ args << "LIMIT"
1926
+ args.concat(limit)
1927
+ end
1909
1928
 
1910
1929
  synchronize do |client|
1911
- client.call([:zrevrangebylex, key, max, min] + args)
1930
+ client.call(args)
1912
1931
  end
1913
1932
  end
1914
1933
 
@@ -1939,21 +1958,21 @@ class Redis
1939
1958
  # @return [Array<String>, Array<[String, Float]>]
1940
1959
  # - when `:with_scores` is not specified, an array of members
1941
1960
  # - when `:with_scores` is specified, an array with `[member, score]` pairs
1942
- def zrangebyscore(key, min, max, options = {})
1943
- args = []
1944
-
1945
- with_scores = options[:with_scores] || options[:withscores]
1961
+ def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)
1962
+ args = [:zrangebyscore, key, min, max]
1946
1963
 
1947
1964
  if with_scores
1948
1965
  args << "WITHSCORES"
1949
1966
  block = FloatifyPairs
1950
1967
  end
1951
1968
 
1952
- limit = options[:limit]
1953
- args.concat(["LIMIT"] + limit) if limit
1969
+ if limit
1970
+ args << "LIMIT"
1971
+ args.concat(limit)
1972
+ end
1954
1973
 
1955
1974
  synchronize do |client|
1956
- client.call([:zrangebyscore, key, min, max] + args, &block)
1975
+ client.call(args, &block)
1957
1976
  end
1958
1977
  end
1959
1978
 
@@ -1971,21 +1990,21 @@ class Redis
1971
1990
  # # => [["b", 64.0], ["a", 32.0]]
1972
1991
  #
1973
1992
  # @see #zrangebyscore
1974
- def zrevrangebyscore(key, max, min, options = {})
1975
- args = []
1976
-
1977
- with_scores = options[:with_scores] || options[:withscores]
1993
+ def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)
1994
+ args = [:zrevrangebyscore, key, max, min]
1978
1995
 
1979
1996
  if with_scores
1980
- args << ["WITHSCORES"]
1997
+ args << "WITHSCORES"
1981
1998
  block = FloatifyPairs
1982
1999
  end
1983
2000
 
1984
- limit = options[:limit]
1985
- args.concat(["LIMIT"] + limit) if limit
2001
+ if limit
2002
+ args << "LIMIT"
2003
+ args.concat(limit)
2004
+ end
1986
2005
 
1987
2006
  synchronize do |client|
1988
- client.call([:zrevrangebyscore, key, max, min] + args, &block)
2007
+ client.call(args, &block)
1989
2008
  end
1990
2009
  end
1991
2010
 
@@ -2005,7 +2024,7 @@ class Redis
2005
2024
  # @param [String] max
2006
2025
  # - inclusive maximum score is specified verbatim
2007
2026
  # - exclusive maximum score is specified by prefixing `(`
2008
- # @return [Fixnum] number of members that were removed
2027
+ # @return [Integer] number of members that were removed
2009
2028
  def zremrangebyscore(key, min, max)
2010
2029
  synchronize do |client|
2011
2030
  client.call([:zremrangebyscore, key, min, max])
@@ -2028,7 +2047,7 @@ class Redis
2028
2047
  # @param [String] max
2029
2048
  # - inclusive maximum score is specified verbatim
2030
2049
  # - exclusive maximum score is specified by prefixing `(`
2031
- # @return [Fixnum] number of members in within the specified range
2050
+ # @return [Integer] number of members in within the specified range
2032
2051
  def zcount(key, min, max)
2033
2052
  synchronize do |client|
2034
2053
  client.call([:zcount, key, min, max])
@@ -2048,18 +2067,19 @@ class Redis
2048
2067
  # - `:weights => [Float, Float, ...]`: weights to associate with source
2049
2068
  # sorted sets
2050
2069
  # - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
2051
- # @return [Fixnum] number of elements in the resulting sorted set
2052
- def zinterstore(destination, keys, options = {})
2053
- args = []
2070
+ # @return [Integer] number of elements in the resulting sorted set
2071
+ def zinterstore(destination, keys, weights: nil, aggregate: nil)
2072
+ args = [:zinterstore, destination, keys.size, *keys]
2054
2073
 
2055
- weights = options[:weights]
2056
- args.concat(["WEIGHTS"] + weights) if weights
2074
+ if weights
2075
+ args << "WEIGHTS"
2076
+ args.concat(weights)
2077
+ end
2057
2078
 
2058
- aggregate = options[:aggregate]
2059
- args.concat(["AGGREGATE", aggregate]) if aggregate
2079
+ args << "AGGREGATE" << aggregate if aggregate
2060
2080
 
2061
2081
  synchronize do |client|
2062
- client.call([:zinterstore, destination, keys.size] + keys + args)
2082
+ client.call(args)
2063
2083
  end
2064
2084
  end
2065
2085
 
@@ -2075,40 +2095,46 @@ class Redis
2075
2095
  # - `:weights => [Float, Float, ...]`: weights to associate with source
2076
2096
  # sorted sets
2077
2097
  # - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
2078
- # @return [Fixnum] number of elements in the resulting sorted set
2079
- def zunionstore(destination, keys, options = {})
2080
- args = []
2098
+ # @return [Integer] number of elements in the resulting sorted set
2099
+ def zunionstore(destination, keys, weights: nil, aggregate: nil)
2100
+ args = [:zunionstore, destination, keys.size, *keys]
2081
2101
 
2082
- weights = options[:weights]
2083
- args.concat(["WEIGHTS"] + weights) if weights
2102
+ if weights
2103
+ args << "WEIGHTS"
2104
+ args.concat(weights)
2105
+ end
2084
2106
 
2085
- aggregate = options[:aggregate]
2086
- args.concat(["AGGREGATE", aggregate]) if aggregate
2107
+ args << "AGGREGATE" << aggregate if aggregate
2087
2108
 
2088
2109
  synchronize do |client|
2089
- client.call([:zunionstore, destination, keys.size] + keys + args)
2110
+ client.call(args)
2090
2111
  end
2091
2112
  end
2092
2113
 
2093
2114
  # Get the number of fields in a hash.
2094
2115
  #
2095
2116
  # @param [String] key
2096
- # @return [Fixnum] number of fields in the hash
2117
+ # @return [Integer] number of fields in the hash
2097
2118
  def hlen(key)
2098
2119
  synchronize do |client|
2099
2120
  client.call([:hlen, key])
2100
2121
  end
2101
2122
  end
2102
2123
 
2103
- # Set the string value of a hash field.
2124
+ # Set one or more hash values.
2125
+ #
2126
+ # @example
2127
+ # redis.hset("hash", "f1", "v1", "f2", "v2") # => 2
2128
+ # redis.hset("hash", { "f1" => "v1", "f2" => "v2" }) # => 2
2104
2129
  #
2105
2130
  # @param [String] key
2106
- # @param [String] field
2107
- # @param [String] value
2108
- # @return [Boolean] whether or not the field was **added** to the hash
2109
- def hset(key, field, value)
2131
+ # @param [Array<String> | Hash<String, String>] attrs array or hash of fields and values
2132
+ # @return [Integer] The number of fields that were added to the hash
2133
+ def hset(key, *attrs)
2134
+ attrs = attrs.first.flatten if attrs.size == 1 && attrs.first.is_a?(Hash)
2135
+
2110
2136
  synchronize do |client|
2111
- client.call([:hset, key, field, value], &Boolify)
2137
+ client.call([:hset, key, *attrs])
2112
2138
  end
2113
2139
  end
2114
2140
 
@@ -2197,7 +2223,7 @@ class Redis
2197
2223
  # @see #hmget
2198
2224
  def mapped_hmget(key, *fields)
2199
2225
  hmget(key, *fields) do |reply|
2200
- if reply.kind_of?(Array)
2226
+ if reply.is_a?(Array)
2201
2227
  Hash[fields.zip(reply)]
2202
2228
  else
2203
2229
  reply
@@ -2209,7 +2235,7 @@ class Redis
2209
2235
  #
2210
2236
  # @param [String] key
2211
2237
  # @param [String, Array<String>] field
2212
- # @return [Fixnum] the number of fields that were removed from the hash
2238
+ # @return [Integer] the number of fields that were removed from the hash
2213
2239
  def hdel(key, *fields)
2214
2240
  synchronize do |client|
2215
2241
  client.call([:hdel, key, *fields])
@@ -2231,8 +2257,8 @@ class Redis
2231
2257
  #
2232
2258
  # @param [String] key
2233
2259
  # @param [String] field
2234
- # @param [Fixnum] increment
2235
- # @return [Fixnum] value of the field after incrementing it
2260
+ # @param [Integer] increment
2261
+ # @return [Integer] value of the field after incrementing it
2236
2262
  def hincrby(key, field, increment)
2237
2263
  synchronize do |client|
2238
2264
  client.call([:hincrby, key, field, increment])
@@ -2290,20 +2316,21 @@ class Redis
2290
2316
 
2291
2317
  def subscribed?
2292
2318
  synchronize do |client|
2293
- client.kind_of? SubscribedClient
2319
+ client.is_a? SubscribedClient
2294
2320
  end
2295
2321
  end
2296
2322
 
2297
2323
  # Listen for messages published to the given channels.
2298
2324
  def subscribe(*channels, &block)
2299
- synchronize do |client|
2325
+ synchronize do |_client|
2300
2326
  _subscription(:subscribe, 0, channels, block)
2301
2327
  end
2302
2328
  end
2303
2329
 
2304
- # Listen for messages published to the given channels. Throw a timeout error if there is no messages for a timeout period.
2330
+ # Listen for messages published to the given channels. Throw a timeout error
2331
+ # if there is no messages for a timeout period.
2305
2332
  def subscribe_with_timeout(timeout, *channels, &block)
2306
- synchronize do |client|
2333
+ synchronize do |_client|
2307
2334
  _subscription(:subscribe_with_timeout, timeout, channels, block)
2308
2335
  end
2309
2336
  end
@@ -2311,21 +2338,23 @@ class Redis
2311
2338
  # Stop listening for messages posted to the given channels.
2312
2339
  def unsubscribe(*channels)
2313
2340
  synchronize do |client|
2314
- raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
2341
+ raise "Can't unsubscribe if not subscribed." unless subscribed?
2342
+
2315
2343
  client.unsubscribe(*channels)
2316
2344
  end
2317
2345
  end
2318
2346
 
2319
2347
  # Listen for messages published to channels matching the given patterns.
2320
2348
  def psubscribe(*channels, &block)
2321
- synchronize do |client|
2349
+ synchronize do |_client|
2322
2350
  _subscription(:psubscribe, 0, channels, block)
2323
2351
  end
2324
2352
  end
2325
2353
 
2326
- # Listen for messages published to channels matching the given patterns. Throw a timeout error if there is no messages for a timeout period.
2354
+ # Listen for messages published to channels matching the given patterns.
2355
+ # Throw a timeout error if there is no messages for a timeout period.
2327
2356
  def psubscribe_with_timeout(timeout, *channels, &block)
2328
- synchronize do |client|
2357
+ synchronize do |_client|
2329
2358
  _subscription(:psubscribe_with_timeout, timeout, channels, block)
2330
2359
  end
2331
2360
  end
@@ -2333,7 +2362,8 @@ class Redis
2333
2362
  # Stop listening for messages posted to channels matching the given patterns.
2334
2363
  def punsubscribe(*channels)
2335
2364
  synchronize do |client|
2336
- raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
2365
+ raise "Can't unsubscribe if not subscribed." unless subscribed?
2366
+
2337
2367
  client.punsubscribe(*channels)
2338
2368
  end
2339
2369
  end
@@ -2378,7 +2408,7 @@ class Redis
2378
2408
  # @see #multi
2379
2409
  def watch(*keys)
2380
2410
  synchronize do |client|
2381
- res = client.call([:watch] + keys)
2411
+ res = client.call([:watch, *keys])
2382
2412
 
2383
2413
  if block_given?
2384
2414
  begin
@@ -2408,14 +2438,13 @@ class Redis
2408
2438
  end
2409
2439
 
2410
2440
  def pipelined
2411
- synchronize do |client|
2441
+ synchronize do |prior_client|
2412
2442
  begin
2413
- pipeline = Pipeline.new(@client)
2414
- original, @client = @client, pipeline
2443
+ @client = Pipeline.new(prior_client)
2415
2444
  yield(self)
2416
- original.call_pipeline(@client)
2445
+ prior_client.call_pipeline(@client)
2417
2446
  ensure
2418
- @client = original
2447
+ @client = prior_client
2419
2448
  end
2420
2449
  end
2421
2450
  end
@@ -2451,17 +2480,16 @@ class Redis
2451
2480
  # @see #watch
2452
2481
  # @see #unwatch
2453
2482
  def multi
2454
- synchronize do |client|
2483
+ synchronize do |prior_client|
2455
2484
  if !block_given?
2456
- client.call([:multi])
2485
+ prior_client.call([:multi])
2457
2486
  else
2458
2487
  begin
2459
- pipeline = Pipeline::Multi.new(@client)
2460
- original, @client = @client, pipeline
2488
+ @client = Pipeline::Multi.new(prior_client)
2461
2489
  yield(self)
2462
- original.call_pipeline(pipeline)
2490
+ prior_client.call_pipeline(@client)
2463
2491
  ensure
2464
- @client = original
2492
+ @client = prior_client
2465
2493
  end
2466
2494
  end
2467
2495
  end
@@ -2608,18 +2636,12 @@ class Redis
2608
2636
  _eval(:evalsha, args)
2609
2637
  end
2610
2638
 
2611
- def _scan(command, cursor, args, options = {}, &block)
2639
+ def _scan(command, cursor, args, match: nil, count: nil, &block)
2612
2640
  # SSCAN/ZSCAN/HSCAN already prepend the key to +args+.
2613
2641
 
2614
2642
  args << cursor
2615
-
2616
- if match = options[:match]
2617
- args.concat(["MATCH", match])
2618
- end
2619
-
2620
- if count = options[:count]
2621
- args.concat(["COUNT", count])
2622
- end
2643
+ args << "MATCH" << match if match
2644
+ args << "COUNT" << count if count
2623
2645
 
2624
2646
  synchronize do |client|
2625
2647
  client.call([command] + args, &block)
@@ -2641,8 +2663,8 @@ class Redis
2641
2663
  # - `:count => Integer`: return count keys at most per iteration
2642
2664
  #
2643
2665
  # @return [String, Array<String>] the next cursor and all found keys
2644
- def scan(cursor, options={})
2645
- _scan(:scan, cursor, [], options)
2666
+ def scan(cursor, **options)
2667
+ _scan(:scan, cursor, [], **options)
2646
2668
  end
2647
2669
 
2648
2670
  # Scan the keyspace
@@ -2660,11 +2682,12 @@ class Redis
2660
2682
  # - `:count => Integer`: return count keys at most per iteration
2661
2683
  #
2662
2684
  # @return [Enumerator] an enumerator for all found keys
2663
- def scan_each(options={}, &block)
2664
- return to_enum(:scan_each, options) unless block_given?
2685
+ def scan_each(**options, &block)
2686
+ return to_enum(:scan_each, **options) unless block_given?
2687
+
2665
2688
  cursor = 0
2666
2689
  loop do
2667
- cursor, keys = scan(cursor, options)
2690
+ cursor, keys = scan(cursor, **options)
2668
2691
  keys.each(&block)
2669
2692
  break if cursor == "0"
2670
2693
  end
@@ -2681,8 +2704,8 @@ class Redis
2681
2704
  # - `:count => Integer`: return count keys at most per iteration
2682
2705
  #
2683
2706
  # @return [String, Array<[String, String]>] the next cursor and all found keys
2684
- def hscan(key, cursor, options={})
2685
- _scan(:hscan, cursor, [key], options) do |reply|
2707
+ def hscan(key, cursor, **options)
2708
+ _scan(:hscan, cursor, [key], **options) do |reply|
2686
2709
  [reply[0], reply[1].each_slice(2).to_a]
2687
2710
  end
2688
2711
  end
@@ -2698,11 +2721,12 @@ class Redis
2698
2721
  # - `:count => Integer`: return count keys at most per iteration
2699
2722
  #
2700
2723
  # @return [Enumerator] an enumerator for all found keys
2701
- def hscan_each(key, options={}, &block)
2702
- return to_enum(:hscan_each, key, options) unless block_given?
2724
+ def hscan_each(key, **options, &block)
2725
+ return to_enum(:hscan_each, key, **options) unless block_given?
2726
+
2703
2727
  cursor = 0
2704
2728
  loop do
2705
- cursor, values = hscan(key, cursor, options)
2729
+ cursor, values = hscan(key, cursor, **options)
2706
2730
  values.each(&block)
2707
2731
  break if cursor == "0"
2708
2732
  end
@@ -2720,8 +2744,8 @@ class Redis
2720
2744
  #
2721
2745
  # @return [String, Array<[String, Float]>] the next cursor and all found
2722
2746
  # members and scores
2723
- def zscan(key, cursor, options={})
2724
- _scan(:zscan, cursor, [key], options) do |reply|
2747
+ def zscan(key, cursor, **options)
2748
+ _scan(:zscan, cursor, [key], **options) do |reply|
2725
2749
  [reply[0], FloatifyPairs.call(reply[1])]
2726
2750
  end
2727
2751
  end
@@ -2737,11 +2761,12 @@ class Redis
2737
2761
  # - `:count => Integer`: return count keys at most per iteration
2738
2762
  #
2739
2763
  # @return [Enumerator] an enumerator for all found scores and members
2740
- def zscan_each(key, options={}, &block)
2741
- return to_enum(:zscan_each, key, options) unless block_given?
2764
+ def zscan_each(key, **options, &block)
2765
+ return to_enum(:zscan_each, key, **options) unless block_given?
2766
+
2742
2767
  cursor = 0
2743
2768
  loop do
2744
- cursor, values = zscan(key, cursor, options)
2769
+ cursor, values = zscan(key, cursor, **options)
2745
2770
  values.each(&block)
2746
2771
  break if cursor == "0"
2747
2772
  end
@@ -2758,8 +2783,8 @@ class Redis
2758
2783
  # - `:count => Integer`: return count keys at most per iteration
2759
2784
  #
2760
2785
  # @return [String, Array<String>] the next cursor and all found members
2761
- def sscan(key, cursor, options={})
2762
- _scan(:sscan, cursor, [key], options)
2786
+ def sscan(key, cursor, **options)
2787
+ _scan(:sscan, cursor, [key], **options)
2763
2788
  end
2764
2789
 
2765
2790
  # Scan a set
@@ -2773,11 +2798,12 @@ class Redis
2773
2798
  # - `:count => Integer`: return count keys at most per iteration
2774
2799
  #
2775
2800
  # @return [Enumerator] an enumerator for all keys in the set
2776
- def sscan_each(key, options={}, &block)
2777
- return to_enum(:sscan_each, key, options) unless block_given?
2801
+ def sscan_each(key, **options, &block)
2802
+ return to_enum(:sscan_each, key, **options) unless block_given?
2803
+
2778
2804
  cursor = 0
2779
2805
  loop do
2780
- cursor, keys = sscan(key, cursor, options)
2806
+ cursor, keys = sscan(key, cursor, **options)
2781
2807
  keys.each(&block)
2782
2808
  break if cursor == "0"
2783
2809
  end
@@ -2800,7 +2826,7 @@ class Redis
2800
2826
  # union of the HyperLogLogs contained in the keys.
2801
2827
  #
2802
2828
  # @param [String, Array<String>] keys
2803
- # @return [Fixnum]
2829
+ # @return [Integer]
2804
2830
  def pfcount(*keys)
2805
2831
  synchronize do |client|
2806
2832
  client.call([:pfcount] + keys)
@@ -2823,7 +2849,7 @@ class Redis
2823
2849
  #
2824
2850
  # @param [String] key
2825
2851
  # @param [Array] member arguemnts for member or members: longitude, latitude, name
2826
- # @return [Intger] number of elements added to the sorted set
2852
+ # @return [Integer] number of elements added to the sorted set
2827
2853
  def geoadd(key, *member)
2828
2854
  synchronize do |client|
2829
2855
  client.call([:geoadd, key, *member])
@@ -2841,12 +2867,12 @@ class Redis
2841
2867
  end
2842
2868
  end
2843
2869
 
2844
-
2845
2870
  # Query a sorted set representing a geospatial index to fetch members matching a
2846
2871
  # given maximum distance from a point
2847
2872
  #
2848
2873
  # @param [Array] args key, longitude, latitude, radius, unit(m|km|ft|mi)
2849
- # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center
2874
+ # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest
2875
+ # or the farthest to the nearest relative to the center
2850
2876
  # @param [Integer] count limit the results to the first N matching items
2851
2877
  # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
2852
2878
  # @return [Array<String>] may be changed with `options`
@@ -2863,7 +2889,8 @@ class Redis
2863
2889
  # given maximum distance from an already existing member
2864
2890
  #
2865
2891
  # @param [Array] args key, member, radius, unit(m|km|ft|mi)
2866
- # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center
2892
+ # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest
2893
+ # to the nearest relative to the center
2867
2894
  # @param [Integer] count limit the results to the first N matching items
2868
2895
  # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
2869
2896
  # @return [Array<String>] may be changed with `options`
@@ -2880,7 +2907,8 @@ class Redis
2880
2907
  #
2881
2908
  # @param [String] key
2882
2909
  # @param [String, Array<String>] member one member or array of members
2883
- # @return [Array<Array<String>, nil>] returns array of elements, where each element is either array of longitude and latitude or nil
2910
+ # @return [Array<Array<String>, nil>] returns array of elements, where each
2911
+ # element is either array of longitude and latitude or nil
2884
2912
  def geopos(key, member)
2885
2913
  synchronize do |client|
2886
2914
  client.call([:geopos, key, member])
@@ -2944,10 +2972,14 @@ class Redis
2944
2972
  # @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
2945
2973
  #
2946
2974
  # @return [String] the entry id
2947
- def xadd(key, entry, opts = {})
2975
+ def xadd(key, entry, approximate: nil, maxlen: nil, id: '*')
2948
2976
  args = [:xadd, key]
2949
- args.concat(['MAXLEN', (opts[:approximate] ? '~' : nil), opts[:maxlen]].compact) if opts[:maxlen]
2950
- args << (opts[:id] || '*')
2977
+ if maxlen
2978
+ args << "MAXLEN"
2979
+ args << "~" if approximate
2980
+ args << maxlen
2981
+ end
2982
+ args << id
2951
2983
  args.concat(entry.to_a.flatten)
2952
2984
  synchronize { |client| client.call(args) }
2953
2985
  end
@@ -3002,8 +3034,8 @@ class Redis
3002
3034
  # @param count [Integer] the number of entries as limit
3003
3035
  #
3004
3036
  # @return [Array<Array<String, Hash>>] the ids and entries pairs
3005
- def xrange(key, start = '-', _end = '+', count: nil)
3006
- args = [:xrange, key, start, _end]
3037
+ def xrange(key, start = '-', range_end = '+', count: nil)
3038
+ args = [:xrange, key, start, range_end]
3007
3039
  args.concat(['COUNT', count]) if count
3008
3040
  synchronize { |client| client.call(args, &HashifyStreamEntries) }
3009
3041
  end
@@ -3025,8 +3057,8 @@ class Redis
3025
3057
  # @params count [Integer] the number of entries as limit
3026
3058
  #
3027
3059
  # @return [Array<Array<String, Hash>>] the ids and entries pairs
3028
- def xrevrange(key, _end = '+', start = '-', count: nil)
3029
- args = [:xrevrange, key, _end, start]
3060
+ def xrevrange(key, range_end = '+', start = '-', count: nil)
3061
+ args = [:xrevrange, key, range_end, start]
3030
3062
  args.concat(['COUNT', count]) if count
3031
3063
  synchronize { |client| client.call(args, &HashifyStreamEntries) }
3032
3064
  end
@@ -3118,12 +3150,12 @@ class Redis
3118
3150
  # @option opts [Boolean] :noack whether message loss is acceptable or not
3119
3151
  #
3120
3152
  # @return [Hash{String => Hash{String => Hash}}] the entries
3121
- def xreadgroup(group, consumer, keys, ids, opts = {})
3153
+ def xreadgroup(group, consumer, keys, ids, count: nil, block: nil, noack: nil)
3122
3154
  args = [:xreadgroup, 'GROUP', group, consumer]
3123
- args << 'COUNT' << opts[:count] if opts[:count]
3124
- args << 'BLOCK' << opts[:block].to_i if opts[:block]
3125
- args << 'NOACK' if opts[:noack]
3126
- _xread(args, keys, ids, opts[:block])
3155
+ args << 'COUNT' << count if count
3156
+ args << 'BLOCK' << block.to_i if block
3157
+ args << 'NOACK' if noack
3158
+ _xread(args, keys, ids, block)
3127
3159
  end
3128
3160
 
3129
3161
  # Removes one or multiple entries from the pending entries list of a stream consumer group.
@@ -3233,8 +3265,8 @@ class Redis
3233
3265
  when "get-master-addr-by-name"
3234
3266
  reply
3235
3267
  else
3236
- if reply.kind_of?(Array)
3237
- if reply[0].kind_of?(Array)
3268
+ if reply.is_a?(Array)
3269
+ if reply[0].is_a?(Array)
3238
3270
  reply.map(&Hashify)
3239
3271
  else
3240
3272
  Hashify.call(reply)
@@ -3258,12 +3290,17 @@ class Redis
3258
3290
  def cluster(subcommand, *args)
3259
3291
  subcommand = subcommand.to_s.downcase
3260
3292
  block = case subcommand
3261
- when 'slots' then HashifyClusterSlots
3262
- when 'nodes' then HashifyClusterNodes
3263
- when 'slaves' then HashifyClusterSlaves
3264
- when 'info' then HashifyInfo
3265
- else Noop
3266
- end
3293
+ when 'slots'
3294
+ HashifyClusterSlots
3295
+ when 'nodes'
3296
+ HashifyClusterNodes
3297
+ when 'slaves'
3298
+ HashifyClusterSlaves
3299
+ when 'info'
3300
+ HashifyInfo
3301
+ else
3302
+ Noop
3303
+ end
3267
3304
 
3268
3305
  # @see https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb#L127 raw reply expected
3269
3306
  block = Noop unless @cluster_mode
@@ -3298,21 +3335,21 @@ class Redis
3298
3335
  return @original_client.connection_info if @cluster_mode
3299
3336
 
3300
3337
  {
3301
- host: @original_client.host,
3302
- port: @original_client.port,
3303
- db: @original_client.db,
3304
- id: @original_client.id,
3338
+ host: @original_client.host,
3339
+ port: @original_client.port,
3340
+ db: @original_client.db,
3341
+ id: @original_client.id,
3305
3342
  location: @original_client.location
3306
3343
  }
3307
3344
  end
3308
3345
 
3309
- def method_missing(command, *args)
3346
+ def method_missing(command, *args) # rubocop:disable Style/MissingRespondToMissing
3310
3347
  synchronize do |client|
3311
3348
  client.call([command] + args)
3312
3349
  end
3313
3350
  end
3314
3351
 
3315
- private
3352
+ private
3316
3353
 
3317
3354
  # Commands returning 1 for true and 0 for false may be executed in a pipeline
3318
3355
  # where the method call will return nil. Propagate the nil instead of falsely
@@ -3384,18 +3421,21 @@ private
3384
3421
  end
3385
3422
  }
3386
3423
 
3424
+ EMPTY_STREAM_RESPONSE = [nil].freeze
3425
+ private_constant :EMPTY_STREAM_RESPONSE
3426
+
3387
3427
  HashifyStreamEntries = lambda { |reply|
3388
- reply.map do |entry_id, values|
3428
+ reply.compact.map do |entry_id, values|
3389
3429
  [entry_id, values.each_slice(2).to_h]
3390
3430
  end
3391
3431
  }
3392
3432
 
3393
3433
  HashifyStreamPendings = lambda { |reply|
3394
3434
  {
3395
- 'size' => reply[0],
3435
+ 'size' => reply[0],
3396
3436
  'min_entry_id' => reply[1],
3397
3437
  'max_entry_id' => reply[2],
3398
- 'consumers' => reply[3].nil? ? {} : reply[3].to_h
3438
+ 'consumers' => reply[3].nil? ? {} : reply[3].to_h
3399
3439
  }
3400
3440
  }
3401
3441
 
@@ -3404,8 +3444,8 @@ private
3404
3444
  {
3405
3445
  'entry_id' => arr[0],
3406
3446
  'consumer' => arr[1],
3407
- 'elapsed' => arr[2],
3408
- 'count' => arr[3]
3447
+ 'elapsed' => arr[2],
3448
+ 'count' => arr[3]
3409
3449
  }
3410
3450
  end
3411
3451
  }
@@ -3413,15 +3453,15 @@ private
3413
3453
  HashifyClusterNodeInfo = lambda { |str|
3414
3454
  arr = str.split(' ')
3415
3455
  {
3416
- 'node_id' => arr[0],
3417
- 'ip_port' => arr[1],
3418
- 'flags' => arr[2].split(','),
3456
+ 'node_id' => arr[0],
3457
+ 'ip_port' => arr[1],
3458
+ 'flags' => arr[2].split(','),
3419
3459
  'master_node_id' => arr[3],
3420
- 'ping_sent' => arr[4],
3421
- 'pong_recv' => arr[5],
3422
- 'config_epoch' => arr[6],
3423
- 'link_state' => arr[7],
3424
- 'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-'))
3460
+ 'ping_sent' => arr[4],
3461
+ 'pong_recv' => arr[5],
3462
+ 'config_epoch' => arr[6],
3463
+ 'link_state' => arr[7],
3464
+ 'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-'))
3425
3465
  }
3426
3466
  }
3427
3467
 
@@ -3432,9 +3472,9 @@ private
3432
3472
  replicas = arr[3..-1].map { |r| { 'ip' => r[0], 'port' => r[1], 'node_id' => r[2] } }
3433
3473
  {
3434
3474
  'start_slot' => first_slot,
3435
- 'end_slot' => last_slot,
3436
- 'master' => master,
3437
- 'replicas' => replicas
3475
+ 'end_slot' => last_slot,
3476
+ 'master' => master,
3477
+ 'replicas' => replicas
3438
3478
  }
3439
3479
  end
3440
3480
  }