2013-08-15 5 views
16

Gibt es eine Möglichkeit, den folgenden Code zu vereinfachen?Wie man eine Ruby-Methode in einen Block umwandelt?

Dateinamen ist eine Liste von Dateinamen (Strings), z. [ "Foo.txt", "bar.c", "baz.yaml"]

filenames.map { |f| File.size(f) } 

Gibt es eine Möglichkeit "File.size" in ein proc oder blockieren zu drehen? Für Methoden auf vorhandenen Objekten kann ich &:method tun. Gibt es etwas Analoges für Modulebene-Methoden?

Antwort

22

können Sie Object#method(method_name) verwenden (obwohl AFAIK nicht idiomatischen ist):

filenames.map(&File.method(:size)) 
+0

Ja .. das ist das was ich geben wollte .. Aber du hast mich geschlagen. Danke, dass du das präsentiert hast. * + 1 *. –

+0

Interessant, ich hätte falsch geraten wegen der verbindlichen Anordnung von '&'. – DGM

4
filesize = proc { |f| File.size(f) } 
filenames.map(&filesize) 
+0

+1 Sehr cool. Warum habe ich nicht daran gedacht? Jetzt habe ich einen tollen neuen Refactoring-Trick. –

+4

Das vereinfacht das nicht, es bringt zusätzliche Komplexität. –

+2

@ MartinC.Martin In der Tat, es vereinfacht es nicht. Aber genau das hast du gefragt. Diese Antwort macht den Ausdruck sehr einfach zu einem Proc. Sich selbst die Schuld zuschreiben. Es ist deine Schuld, nicht Logans. – sawa

4

Stdlib des Pathname bieten einen objektorientierten Ansatz auf Dateien und Verzeichnisse. Vielleicht gibt es eine Möglichkeit, Ihre filelist, z. Statt:

filenames = Dir.entries(".") 
filenames.map { |f| File.size(f) } 

Sie verwenden würden:

require 'pathname' 
filenames = Pathname.new(".").entries 
filenames.map(&:size) 
+2

Danke, das löst mein eigentliches Problem, obwohl es den Titel der Frage nicht beantwortet. –