Forum: PC-Programmierung Merkwürdiges Rails-4.2-Problem


von Uhu U. (uhu)


Lesenswert?

Aus einer Datenbank wird ein Objekt der class A geladen.

In einer Objektvariablen t steht ein String, der den Namen einer 
(definierten) Klasse "Beobachtung" darstellt. (Beobachtung ist von 
ActiveRecord::Base abgeleitet.)

Es wird folgender after_find - Filter ausgeführt:
1
after_find do |f|
2
   # f.t == "Beobachtung"
3
4
   f.t = eval(f.t)
5
6
   # f.t sollte jetzt class<Beobachtung> sein, 
7
   # ist aber immer noch "Beobachtung"
8
end

Wenn ich einen Haltepunkt in den Filter setze und den Befehl
f.t = eval(f.t)
in byebug ausführe und anschließend p f.t eingebe, wird das Class-Objekt 
angezeigt, dessen Name zu Beginn in f.t stand.

Wenn ich den Filterausdruck unter rails ausführen lasse, enthält f.t 
anschließend nicht das Class-Objekt, sondern den String.

Besonders irritiert mich, dass die Konstruktion
1
  v = "Beobachtung"
2
  v = eval(v)
unter Rails 3 mit ruby 1.8.7 wie gedacht funktioniert: v enthält 
hinterher das Class-Objekt

Was ist da los?


Nachtrag:
Wenn ich im after_find-Filter probeweise
1
  f.t = Beobachtung
schreibe, ist f.t nach Ausführung des Befehls unverändert - es liegt 
also nicht an eval, sondern an der Zuweisung.

: Bearbeitet durch User
von D. I. (Gast)


Lesenswert?

Welche Rubyversion verwendest du mit Rails 4.2?

U.a. aus Gründen der Wartbarkeit würde ich zu einer eval-freien Lösung 
raten ;) trotzdem interessant zu erforschen was genau das Problem ist

von Uhu U. (uhu)


Lesenswert?

2.1.5p273

> U.a. aus Gründen der Wartbarkeit würde ich zu einer eval-freien Lösung
> raten ;)

Es liegt nicht an eval - das wird wohl auch künftig kaum aus einem 
Kassennamen was anderes, als das class-Objekt machen...

Das ganze Dingens ist eine abstrakte Klasse für eine Suchmaschine, die 
verschiedene Tabellen der DB durchsuchen soll. Die jeweilige Tabelle 
wird als Verweis auf das zugehörige ActiveRecord-Objekt gespeichert.

Da diese Suchklassen selbst in der DB gespeichert werden, ersetze ich 
den Verweis auf die Zielklasse durch ihren Klassennamen, bevor 
geschrieben wird und umgekehrt beim Wiedereinlesen - und da klemmts.

> trotzdem interessant zu erforschen was genau das Problem ist

Ich wühle mich gerade durch den Zuweisungscode - reichlich 
unübersichtlich...

Gibt es immer noch keinen funktionsfähigen Source-Debugger, mit dem man 
sich ohne ständige Tastaturakrobatik durch die Quelltexte hangeln kann?

: Bearbeitet durch User
von D. I. (Gast)


Lesenswert?

Uhu U. schrieb:
> Gibt es immer noch keinen funktionsfähigen Source-Debugger, mit dem man
> sich ohne ständige Tastaturakrobatik durch die Quelltexte hangeln kann?

Was verwendest du denn? Ich verwende die Rubymine IDE, damit finde ich 
kann man ganz gut debuggen.

von Uhu U. (uhu)


Lesenswert?

Ich benutze derzeit pry-byebug. Ich werde mir die Rubymine IDE mal 
ansehen.

Eclipse hat wohl auch einen Debugger, aber mit dem Monstrum konnte ich 
mich noch nie anfreunden...

von Olaf B. (Firma: OBUP) (obrecht)


Lesenswert?

Hi Uhu Uhuhu,

such bitte nach "Ruby symbol to class"

Es gibt unter Object/Module die Methode "const_get"

Bsp.:
1
class Test
2
end
3
4
test_const = Object.const_get(:Test)
5
test_object = test_object.new
6
7
puts test_object.inspect

mfg

Olaf

P.S.: eval ist böse >> s. Code-Injection durch fremden - nicht von Dir - 
stammenden Code

von Uhu U. (uhu)


Lesenswert?

http://stackoverflow.com/questions/1235593/ruby-symbol-to-class erste 
Antwort zweite Variante ist fast genau das, was ich mache: ich habe kein 
Symbol, sondern gleich den String.

Dass eval irgend wann mal was anderes, als das class-Objekt zurückgibt, 
wenn man es mit dem Namen der Klasse als String füttert, halte ich für 
ausgeschlossen.

> P.S.: eval ist böse >> s. Code-Injection durch fremden - nicht von Dir -
> stammenden Code

So platt sehe ich das nicht. Wenn sichergestellt ist, dass der Ausdruck, 
der evaluiert wird, nicht von außen eingegeben werden kann, kann nichts 
passieren.

: Bearbeitet durch User
von Uhu U. (uhu)


Lesenswert?

Mittlerweile habe ich mir die Testversion von RubyMine besorgt und die 
Sache herunter debugt: ActiveRecord scheint automatisch class-Objekte, 
die an Attribute zugewiesen werden sollen, durch ihren textuellen Namen 
zu ersetzen. Die ganze Chose ist auch mit dem schönen Debugger von 
RubyMine ziemlich unübersichtlich und wo der Trick genau gemacht wird, 
habe ich noch nicht heraus gefunden.

Ich habe das Problem jetzt so gelöst, dass ich in dem Attribut immer den 
Namen als String halte und bei Bedarf daraus das class-Object evaluiere.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.