John
John

Reputation: 634

Call methods from blocks

I am using connection_pool to manage my connections to redis, at the moment I need to use $redis.with {|conn| conn.set("key", 1)} to set a key.

How can I do something like

redis.set("key", 1)

and have the same effect as the above line.

Or at least

redis(set("key", 1))

Upvotes: 0

Views: 94

Answers (3)

Sumit Munot
Sumit Munot

Reputation: 3868

Two main ways to receive blocks in a method in Ruby:

First is to use the yield keyword like so:

def speak
  puts yield
end

speak { "Hello" }
# Hello
#  => nil

The other is to prefix the last argument in a method signature with an ampersand which will then create a Proc object from any block passed in.

This object can then be executed with the call method like so:

def speak(&block)
  puts block.call
end

speak { "Hello" }
# Hello
#  => nil

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121010

Although I see no reason in doing what you’ve asked, here we go:

class << redis
  def my_set key, value
    $redis.with { |conn| conn.set key, value }
  end
end

and then:

redis.my_set 'key', 1

For all the methods of interest:

class << redis
  %i(set get foo bar).each do |m|
    class_eval <<-CEEOF
      def my_#{m} *args
        $redis.with { |conn| conn.#{m} *args }
      end
    CEEOF
  end
end

The list of methods might be automatically yielded from conn.instance_methods(false).

Upvotes: 1

Simone Carletti
Simone Carletti

Reputation: 176552

According to the documentation:

You can use ConnectionPool::Wrapper to wrap a single global connection, making it easier to port your connection code over time:

$redis = ConnectionPool::Wrapper.new(size: 5, timeout: 3) { Redis.connect }
$redis.sadd('foo', 1)
$redis.smembers('foo')

The wrapper uses method_missing to checkout a connection, run the requested method and then immediately check the connection back into the pool. It's not high-performance so you'll want to port your performance sensitive code to use with as soon as possible.

But I suspect it would be just a workaround, the way you are doing it right now seem to be the way the library is designed to work.

Upvotes: 1

Related Questions