2016-03-28 13 views
0

ich die folgende Klasse erstellt:define_method gibt nicht definierte Methode `jedes‘ für nil: NilClass

class Decorator < OpenStruct 
    def initialize(options={}) 
     define_predicate options 
     super(options) 
    end 

    def define_predicate(options) 
     options.each do |k,v| 
     define_method "#{k}?" do 
      v.present? 
     end 
     end 
    end 
    end 

Ich möchte folgendes in der Lage sein zu tun:

decor = Decorator.new({ highlight: 'light', color: 'green' }) 
if decor.highlight? 
    puts decor.highlight 
end 
if decor.color? 
    puts decor.color 
end 

Leider, wenn ich versuche, initialisieren der Decorator-Klasse, erhalte ich folgende Fehlermeldung:

NoMethodError: undefined method `each' for nil:NilClass 
    from /Users/donato/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/ostruct.rb:245:in `inspect' 
    from /Users/donato/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/ostruct.rb:187:in `method_missing' 
    from (irb):16:in `block in define_predicate' 
    from (irb):15:in `each' 
    from (irb):15:in `define_predicate' 
    from (irb):10:in `initialize' 
    from (irb):22:in `new' 

Warum define_method diesen Fehler werfen?

Dies funktioniert:

class Decorator < OpenStruct 
    def initialize(options={}) 
     Decorator.define_predicate options 
     super(options) 
    end 

    def self.define_predicate(options) 
     options.each do |k,v| 
     define_method "#{k}?" do 
      v.present? 
     end 
     end 
    end 
    end 
+0

'define_method' löst den Fehler aus, es wirft es nicht. 'OpenStruct' wirft den Fehler über' method_missing', weil es kein Attribut namens 'define_method' finden kann. Hinweis: Woher kommt ['define_method'] (http://ruby-doc.org/core-2.3.0/Module.html#method-i-define_method) und warum sollte es nicht eine Instanzmethode in Ihrem sein? Klasse? Ich bin in Eile oder ich würde mehr sagen. –

+0

Ich sehe, define_method ist in Module definiert, und so muss ich im Klassenkontext verwenden. – Donato

+0

Vielleicht kein exaktes Duplikat, aber die Antworten sind die gleichen: benutze ['define_singleton_method'] (http://ruby-doc.org/core-2.3.0/Object.html#method-i-define_singleton_method) wo du bist versuche 'define_method' zu verwenden. –

Antwort

0

define_method ist eine Klassenmethode. Im ersten Fall wird define_method an der Objektinstanz ausgelöst.

Verwandte Themen