34 Stimmen

Ruby: Wie man mehrere Methodenaufrufe mit "send" verkettet

Es muss doch einen eingebauten Weg geben, dies zu tun, oder?

class Object
  def send_chain(arr)
    o=self
    arr.each{|a| o=o.send(a) }
    return o
  end
end

68voto

Joe Punkte 676

Ich bin gerade auf dieses Dokument gestoßen, das wirklich nach einer Injektion schreit:

def send_chain(arr)
  arr.inject(self) {|o, a| o.send(a) }
end

10voto

dgilperez Punkte 10318

Falls Sie Argumente an die einzelnen Methoden übergeben müssen, können Sie dies verwenden, um auf früheren Antworten aufzubauen:

def send_chain(arr)
  Array(arr).inject(self) { |o, a| o.send(*a) }
end

Sie können die Methode dann wie folgt anwenden:

arr = [:to_i, [:+, 4], :to_s, [:*, 3]]
'1'.send_chain(arr) # => "555"

Diese Methode akzeptiert auch einzelne Argumente.

8voto

edgerunner Punkte 14594

Nein, es gibt ist nicht eine eingebaute Möglichkeit, dies zu tun. Was Sie getan haben, ist einfach und prägnant genug, um nicht zu sagen gefährlich. Seien Sie vorsichtig, wenn Sie es verwenden.

Ein anderer Gedanke ist, dass dies auch auf die Annahme von Argumenten ausgedehnt werden kann:

class Object
  def send_chain(*args)
    o=self
    args.each do |arg|
      case arg
      when Symbol, String
        o = o.send arg # send single symbol or string without arguments
      when Array
        o = o.send *arg # smash the inner array into method name + arguments
      else
        raise ArgumentError
      end
    end
    return o
  end
end

können Sie einen Methodennamen mit seinen Argumenten in einem Array übergeben, z. B;

test = MyObject.new
test.send_chain :a_method, [:a_method_with_args, an_argument, another_argument], :another_method

0voto

Khalil Gharbaoui Punkte 5559

Wie wäre es mit dieser vielseitigen Lösung ohne Verschmutzung der Object Klasse:

def chain_try(arr)
  [arr].flatten.inject(self_or_instance, :try)
end

ou

def chain_send(arr)
  [arr].flatten.inject(self_or_instance, :send)
end

Auf diese Weise kann es eine Symbol , a String oder ein Array mit einer Mischung aus beidem sogar.

Anwendungsbeispiel:

  • chain_send([:method1, 'method2', :method3])
  • chain_send(:one_method)
  • chain_send('one_method')

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X