2012-05-10 10 views
5

sto lavorando con ActiveAttr che ti dà quel bel inizializzazione opzione di blocco tramite:Scrubbing un isolato da una chiamata a super

person = Person.new() do |p| 
    p.first_name = 'test' 
    p.last_name = 'man' 
end 

Tuttavia, in una classe specifica che includono ActiveAttr :: Modello, voglio ignorare questa funzionalità dal momento che voglio usare il blocco per qualcos'altro. Quindi qui si va:

class Imperator::Command 
include ActiveAttr::Model 
end 


class MyCommand < Imperator::Command 

    def initialize(*args, &block) 
    @my_block = block 

    super(*args) 
    end 
end 

Questo fallisce miseramente, perché il blocco viene comunque passato a monte della catena, e, infine, all'interno di ActiveAttr, questo codice viene eseguito:

def initialize(*) 
    super 
    yield self if block_given? 
end 

Quindi, se la mia chiamata appare come così:

MyCommand.new() { |date| date.advance(month: 1) } 

fallisce come segue:

NoMethodError: undefined method `advance' for #<MyCommand:0x007fe432c4fb80> 

dal momento che MyCommand non ha alcun metodo: avanzare la chiamata a MyCommand ovviamente fallisce.

Quindi la mia domanda è questa, c'è un modo per rimuovere il blocco dalla firma del metodo prima di chiamare di nuovo super, in modo che il blocco non viaggi oltre il mio inizializzatore forzato?

risposta

12

Prova

super(*args,&nil) 

L'& fa uso rubino nullo come blocco e rubino sembra abbastanza intelligente per capire questo significa nessun blocco.

+0

Perfetto, non so perché non ci ho pensato. Grazie! – TheDelChop

+1

Questo deve essere un bug rubino, sebbene sia ancora presente in Ruby 2.0 – Mikey

0

Questo è sicuramente un trucco accurato, ma un approccio migliore sarebbe quello di non utilizzare direttamente il modulo ActiveAttr :: Model e includere solo i moduli necessari.

Piuttosto che

class Imperator::Command 
    include ActiveAttr::Model 
end 

fare

class Imperator::Command 
    include BasicModel 
    # include BlockInitialization 
    include Logger 
    include MassAssignmentSecurity 
    include AttributeDefaults 
    include QueryAttributes 
    include TypecastedAttributes 

    def initialize(*args, &block) 
    @my_block = block 
    super(*args) 
    end 
end 

Una volta che si vede la vista esplosa di ActiveAttr :: Modello sta facendo ci possono essere altre cose che in realtà non si vuole. In tal caso basta semplicemente omettere gli include. L'intenzione era quella di fornire un approccio à la carte alla costruzione di modelli.

Problemi correlati