Answer-ID
  • Întrebări
  • Tag-uri
  • Categorii
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 Mike
Mike

Amestecuri de Ruby și metode de apel super

Ok, așa că mi-am refăcut codul în aplicația mea mică Rails, în efortul de a elimina duplicarea și, în general, fă-mi viața mai ușoară (așa cum îmi place o viață ușoară). O parte a acestei refactorizări a fost aceea de a muta codul care este comun pentru două dintre modelele mele într-un modul pe care pot include acolo unde am nevoie.

Până acum, bine. Se pare că va funcționa, dar tocmai am lovit o problemă pe care nu o știu cum să ajung. Modulul (pe care l-am denumit trimis) va fi doar codul care gestionează trimiterea prin fax, e-mail sau imprimarea unui document PDF. Așadar, de exemplu, am o comandă de cumpărare și am ordine de vânzare interne (abreviată imaginativ la ISO).

Problema pe care am lovit-o este că vreau ca unele variabile inițializate (inițializate pentru persoanele care nu scriu corect: P) după încărcarea obiectului, așa că am folosit cârligul after_initialize . Nici o problemă ... până când nu voi adăuga mai multe mixuri.

Problema pe care o am este că pot avea un after_initialize în oricare dintre mixurile mele, așa că trebuie să includ un apel super la începeți să vă asigurați că sunt apelate celelalte apeluri after_initialize mixin. Ceea ce este minunat, până când am terminat apelul de super și am o eroare deoarece nu există nici un super de apel.

Iată un mic exemplu, în cazul în care nu am fost destul de confuz:

class Iso < ActiveRecord::Base
  include Shared::TracksSerialNumberExtension
  include Shared::OrderLines
  extend  Shared::Filtered
  include Sendable::Model

  validates_presence_of   :customer
  validates_associated    :lines

  owned_by                :customer
  order_lines             :despatched # Mixin

  tracks_serial_numbers   :items  # Mixin

  sendable :customer                      # Mixin

  attr_accessor :address

  def initialize( params = nil )
    super
    self.created_at ||= Time.now.to_date
  end
end

Deci, dacă fiecare dintre cele mixte are un apel after_initialize, cu un apel super , cum pot să opresc ultimul apel super de la ridicarea erorii? Cum pot testa că metoda super există înainte să o numesc?

34 2008-08-14T08:30:27+00:00 4
Programare
ruby
ruby-on-rails
Comentarii la întrebare (0)
Orion Edwards
15 august 2008 в 1:30
2008-08-15T01:30:58+00:00
Mai mult
Sursă
Editează
#11719

Mai degrabă decât să verificați dacă metoda super există, puteți să o definiți

class ActiveRecord::Base
    def after_initialize
    end
end

Acest lucru funcționează în testarea mea și nu ar trebui să încalce niciunul din codul dvs. existent, deoarece toate clasele dvs. de altădată care o definesc vor suprasolicita oricum în mod tăcut această metodă

0
0
Comentarii (0)
newtonapple
15 august 2008 в 2:37
2008-08-15T02:37:56+00:00
Mai mult
Sursă
Editează
#11744

Ați încercat alias_method_chain ? Puteți să vă conectați toate apelurile after_initialize . Se comportă ca un decorator: fiecare nouă metodă adaugă un nou nivel de funcționalitate și trece controlul asupra metodei "overridden" pentru a face restul.

0
0
Comentarii (0)
James A. Rosen
15 august 2008 в 5:28
2008-08-15T05:28:04+00:00
Mai mult
Sursă
Editează
#11866

Clasa inclus (lucru care moștenește din ActiveRecord :: Base , care, în acest caz este Iso ) < after_initialize , astfel încât orice soluție, alta decât alias_method_chain (sau altă alianță care salvează originalul), riscă să suprascrie codul. Soluția @Orion Edwards este cea mai bună soluție cu care pot veni. Există și alții, dar sunt mult mai hackiști.

alias_method_chain also has the benefit of creating named versions of the after_initialize method, meaning you can customize the call order in those rare cases that it matters. Otherwise, you're at the mercy of whatever order the including class includes the mixins.

later:

Am trimis o întrebare la lista de discuții rubin-pe-șine-core despre crearea de implementări goale implicite ale tuturor apelurilor. Procesul de economisire le verifică oricum, așa că nu văd de ce nu ar trebui să fie acolo. Singurul dezavantaj este crearea de cadre suplimentare de stivă goale, dar acest lucru este destul de ieftin pentru fiecare implementare cunoscută.

0
0
Comentarii (0)
Utilizator anonim
25 mai 2009 в 10:53
2009-05-25T10:53:52+00:00
Mai mult
Sursă
Editează
#905638

Puteți să aruncați o condiție rapidă acolo:

super if respond_to?('super')

și ar trebui să fii bine - fără a adăuga metode inutile; frumos și curat.

0
0
Comentarii (0)
valo
6 octombrie 2010 в 12:34
2010-10-06T00:34:17+00:00
Mai mult
Sursă
Editează
#3867490

Puteți folosi acest lucru:

super if defined?(super)

Iată un exemplu:

class A
end

class B < A
  def t
    super if defined?(super)
    puts "Hi from B"
  end
end

B.new.t
0
0
Comentarii (0)
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
ID
KO
RU
© Answer-ID 2021
Sursă
https://stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire