Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally call chained method

Tags:

ruby

A chained method should only be called under certain circumstances in the following code.

class Klass
  def foo
    puts 'foo'
    self
  end
  def bar
    puts 'bar'
    self
  end
end

klass = Klass.new
a = 2
id = klass.foo{conditionally chain bar if a == 2}.bar

Can you insert an expression or method between chained methods that conditionally continues or halts the method chain?

like image 817
kreek Avatar asked Aug 14 '26 20:08

kreek


1 Answers

This is simple and who will come after you will understand immediately:

klass = klass.foo
klass = klass.bar if a == 2
etc...

This works well if the chained methods take no arguments

klass.define_singleton_method :chain_if do |b, *s|
  return unless b
  klass = self
  s.each do |x|
    klass = klass.send x
  end
  klass
end

klass.foo.chain_if(true, :foo, :bar).chain_if(false, :bar)

Here some duplicated threads!

conditional chaining in ruby

Add method to an instanced object

Here I found another solution that I personally like:

my_object.tap{|o|o.method_a if a}.tap{|o|o.method_b if b}.tap{|o|o.method_c if c}

EDIT:

beware tap is defined as follows:

class Object
  def tap
    yield self
    self
  end
end

What you need might look like this, if the chained method returns a new immutable object:

class Object
  def tap_and_chain
    yield self
  end
end
like image 128
Damiano Stoffie Avatar answered Aug 16 '26 20:08

Damiano Stoffie