Ok j'ai le code suivant
def update_state_actions
states.each do |state|
@state_turns[state.id] -= 1 if @state_turns[state.id] > 0 && state.auto_removal_timing == 1
end
end
maintenant dans la lignée de ...
@state_turns[state.id] -= 1 if @state_turns[state.id] > 0 && state.auto_removal_timing == 1
il dit l'erreur
in 'block update_state_actions' : Undefined method '>' for nil:NilClass <NoMethodError>
quelle est la cause de l'erreur? Comment se fait-il que >
soit considéré comme une méthode mais qu’il s’agit d’un opérateur logique?
comment est-il considéré comme une méthode mais comme un opérateur logique?
Il n'y a pas de problème avec ça. En Ruby, lorsque vous écrivez une expression telle que 1 + 2
, elle est comprise en interne comme étant 1.+( 2 )
: Appelant la méthode #+
sur le destinataire 1
avec 2
comme argument unique. Une autre façon de comprendre la même chose est que vous envoyez le message [ :+, 2 ]
à l'objet 1
.
quelle est la cause de l'erreur?
Maintenant, dans votre cas, @state_turns[ state.id ]
renvoie nil
pour une raison quelconque. Donc, l'expression @state_turns[state.id] > 0
devient nil > 0
, ce qui, comme je l'ai dit précédemment, est compris comme l'appel de la méthode #>
sur nil
. Mais vous pouvez vérifier que NilClass
, auquel appartient nil
, n'a pas de méthode d'instance #>
définie:
NilClass.instance_methods.include? :> # => false
nil.respond_to? :> # => false
L'exception NoMethodError
est donc une erreur légitime. En soulevant cette erreur, Ruby vous protège: Il vous avertit que votre @state_turns[ state.id ]
n’est pas ce que vous supposez. De cette façon, vous pourrez corriger vos erreurs plus tôt et devenir un programmeur plus efficace. De plus, les exceptions Ruby peuvent être sauvées avec l'instruction begin ... rescue ... end
. Les exceptions Ruby sont généralement des objets très conviviaux et utiles, et vous devez apprendre à définir vos exceptions personnalisées dans vos projets logiciels.
Pour prolonger un peu plus la discussion, voyons d'où vient votre erreur. Lorsque vous écrivez une expression telle que nil > 10
, qui est en fait nil.>( 10 )
, Ruby commence à rechercher la méthode #>
dans la chaîne de recherche de nil
. Vous pouvez voir la chaîne de recherche en tapant:
nil.singleton_class.ancestors #=> [NilClass, Object, Kernel, BasicObject]
La méthode sera recherchée dans chaque module de la chaîne d'ancêtre: Ruby vérifiera d'abord si #>
est défini sur NilClass
, puis sur Object
, puis Kernel
et enfin BasicObject
. Si #>
n'est trouvé dans aucun d'entre eux, Ruby continuera en essayant les méthodes method_missing
, toujours dans l'ordre dans tous les modules de la chaîne de recherche. Si même method_missing
ne gère pas le message :>
, une exception NoMethodError
sera déclenchée. Pour démontrer, définissons la méthode #method_missing
dans Object
en insérant un message personnalisé, qui apparaîtra à la place de NoMethodError
:
class Object
def method_missing( name, *args )
puts "There is no method '##{name}' defined on #{self.class}, you dummy!"
end
end
[ 1, 2, 3 ][ 3 ] > 2
#=> There is no method '#>' defined on NilClass, you dummy!
Pourquoi ne dit-il pas comme NullPointerException
Il n'y a pas une telle exception en Ruby. Vérifiez la classe Exception
de Ruby.
Il doit être converti en variable entière pour effectuer l'opération: