2016-06-10 41 views
3

Ich habe die folgende Methode:funktioniert Memo innerhalb eines Proc?

def download_link_for(site,title=nil) 
    template = proc {|word|(title ? "%s_#{title}_csv": "%s_csv") % word} 

    if site.send(template.call("update")) == false 
    x.a "Generate", :href => "/#{template.call("generate")}/#{site.id}" 
    else 
    xpr "Generating.." 
    end 
    if site.send(template.call("latest")) > 0 && site.send(template.call("update")) == false 
    %| 

    <a href="/#{template.call("download")}/#{site.id}" class="tooltip-left" title="Download the #{title} as a .csv file" id="download_pdf"> 
    <img src="/images/csv_download.png" alt="Download"/> 
    </a> 
    (#{timedate(site.send(template.call("latest")))}) 
    | 

    end 
end 

Das Problem ist, das proc. Ich möchte wissen, ob Memoization innerhalb eines Proc funktioniert? speziell für:

title ? "%s_#{title}_csv": "%s_csv" 

eingedenk mit Ruby 1.8.7 Ich arbeite zwar Informationen über 1.9+ auch begrüßt werden würde.

Das Hauptproblem ist, dass das ternäre Innere des proc nur jemals beim ersten Mal ausgearbeitet werden muss, damit ich es nicht jedes Mal berechnen muss, wenn der proc get aufgerufen wird.

EDIT: Meine Idee war, wie so currying zu verwenden:

template = proc {|tem,word|tem % word}.curry(type ? "%s_#{type}_csv" : "%s_csv") 

aber aus irgendeinem Grund hält es reagiert mit no implicit conversion of String into Integer denke ich, Rubin % als Modul interpretiert und nicht als String-Vorlage. Sogar die Verpackung tem wie so "#{tem}" hat nicht wirklich funktioniert.

Auch würde Curry nicht wirklich für mich arbeiten, wie es in 1.8.7 nicht verfügbar ist, aber es war einen Versuch wert.

+0

Ich würde denken, wenn der Titel immer das gleiche ist (was es muss Ihre Erklärung gegeben werden, dass es am besten sei es im Rahmen außerhalb zu berechnen Dieser Block (als erste Anweisung in 'download_link_for()'). Also: '' 'saved_title = Titel?"% s _ # {Titel} _csv ":"% s_csv "' '' '' 'template = proc { | word | saved_title% word} '' ' (Keine Codeformatierung in Kommentaren, denke ich. Das sind zwei separate Zeilen oben.) –

+0

Ich habe gerade versucht folgendes' template = proc { | word | b || = 0; b + = 1; puts b; (Typ? "% s _ # {Typ} _csv": "% s_csv")% word} 'und es druckte jedes Mal" 1 ", was vermutlich die Frage beantwortet, da es bedeutet, dass b jedes Mal neu berechnet wird Der Proc wird aufgerufen. Ich dachte, ich würde es wahrscheinlich am Anfang berechnen müssen ... warte was, wenn ich es versuchte ... Ich habe eine Idee. – Thermatix

+0

Ist das ein tatsächliches Leistungsproblem? Der Proc scheint nicht viel zu tun ... – Stefan

Antwort

2

Nicht sicher, warum Sie curry müssen. Können Sie nicht einfach eine Instanzvariable verwenden, um die Ergebnisse der ternären Operation zu speichern/zu memoisieren?

template = proc { |word| @title ||= (title ? "%s_#{title}_csv" : "%s_csv"); @title % word } 

In irb:

template = proc { |word| @title ||= word } 

template.call "hello" 
=> "hello" 

template.call "goodbye" 
=> "hello"