Dynamisch erstellen eine multi-dimensionale hash in Ruby
Ich bin ein PHP-Entwickler, die versuchen, um zu gewinnen einige Kenntnisse in Ruby. Eines der Projekte, die ich Schneide meine Zähne auf jetzt ist ein source-code-auditing-tool, das scannt webapp Dateien für potenziell gefährliche Funktionen in mehreren web-Programmiersprachen. Wenn übereinstimmungen gefunden werden, wird das Skript speichert die relevanten Informationen in einem poi
(point-of-interest) - Klasse für die Anzeige später.
Beispiel Instanz der Klasse würde wie folgt Aussehen (modelliert in YAML):
poi:
file_type: "php"
file: "the-scanned-file.php"
line_number: 100
match: "eval()"
snippet: "echo eval()"
Auf dem display, ich organisieren wollen, diese Punkte von Interesse, wie so:
- file_type
-- file
--- match (the searched payload)
So, vor der Präsentation, ich versuche, die Struktur ein flaches array von poi
Objekte in einer hash-spiegelung die Struktur oben. Dies ermöglicht es mir, einfach die Iteration über die Elemente in dem hash zu erzeugen der gewünschten on-screen-Organisation. (Oder zumindest, das ist der plan.)
Und nun zu meiner Frage: wie mache ich das in Ruby?
In PHP, ich könnte etwas tun, wie das wirklich leicht:
<?php
$sorted_pois = array();
foreach($points_of_interest as $point){
$sorted_pois[$point->file_type][$point->file][$point->match][] = $point;
}
?>
Ich habe versucht, die übersetzung, die Gedanken von PHP zu Ruby, wie diese, aber ohne Erfolg:
sorted_pois = {}
@points_of_interest.each_with_index do |point, index|
sorted_pois[point.file_type.to_sym][point.file.to_sym][point.match.to_sym].push point
end
Habe ich damit verbracht, ein paar Stunden auf diesem, und ich bin eine Art schlug meinen Kopf gegen die Wand zu diesem Zeitpunkt, also vermutlich bin ich Weg off-base. Was ist der richtige Weg, um dieses in Ruby?
Update:
Als Referenz, dies ist die genaue Methode, die ich definiert haben:
# sort the points of interest into a structured hash
def sort
sorted_pois = {}
@points_of_interest.each_with_index do |point, index|
sorted_pois[point.file_type.to_sym][point.file.to_sym][point.match.to_sym].push point
end
end
Dies ist die Fehlermeldung die ich erhalte wenn ich den code ausführen:
./lib/models/vulnscanner.rb:63:in `sort': undefined method `[]' for nil:NilClass (NoMethodError)
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `each_with_index'
from ./lib/models/vulnscanner.rb:62:in `each'
from ./lib/models/vulnscanner.rb:62:in `each_with_index'
from ./lib/models/vulnscanner.rb:62:in `sort'
from ./webapp-vulnscan:69
Linie 62 (da können Sie wahrscheinlich folgern) ist diese Zeile in allem:
@points_of_interest.each_with_index do |point, index|
Als eine zusätzliche Referenz, hier ist, was (einem Ausschnitt von) @points_of_interest
aussieht, wenn Umgerechnet auf YAML:
- !ruby/object:PoI
file: models/couponkimoffer.php
file_type: php
group: :dangerous_functions
line_number: "472"
match: `
snippet: ORDER BY `created_at` DESC
- !ruby/object:PoI
file: models/couponkimoffer.php
file_type: php
group: :dangerous_functions
line_number: "818"
match: `
snippet: WHERE `company_slug` = '$company_slug'
- !ruby/object:PoI
file: models/couponkimoffer.php
file_type: php
group: :dangerous_functions
line_number: "819"
match: `
snippet: ORDER BY `created_at` DESC
- Was ist falsch mit dem, was Sie haben? Es tut Ergebnis in der Fehler oder ist die Ausgabe nicht das, was Sie erwarten? Auch die Bereitstellung von Probe-Eingang/ - Ausgang hilfreich.
- vielen Dank für das ansehen. Ich habe gerade aktualisiert die Frage.
Du musst angemeldet sein, um einen Kommentar abzugeben.
@John ' s
Enumerable#group_by
Vorschlag ist eine gute Lösung für Ihre Bedürfnisse. Ein weiterer wäre, erstellen Sie eine auto -, belebenden Hash (wie Sie scheinen zu haben in PHP) so:Beachten Sie, dass diese Art von auto-vivification kann 'gefährlich', wenn Sie den Zugriff auf Schlüssel, die nicht existieren, so erstellt er für Sie:
Können Sie immer noch nutzen Sie die belebenden
default_proc
ohne auf diese Gefahr, wenn Siekey?
um zu testen, zuerst den Schlüssel:FWIW, die Fehler sind Sie immer sagt, "Hey, Sie setzen
[]
nach etwas, das ausgewertetnil
, undnil
nicht[]
- Methode". Speziell der code...ausgewertet, um
nil
(weil die hash-hatte noch kein Wert für diesen Schlüssel), und Sie dann versucht zu Fragen, fürDie Sie interessieren könnten group_by.
Beispiel für die Nutzung:
Das offensichtliche problem mit dem obigen Beispiel ist, dass die verschachtelten hashes und arrays, die Sie versuchen, zu verwenden die es nicht gibt. Versuchen Sie dies: