E
erik blas
I'm reading the why's ruby guide, and i've retyped a class in the guide
to use through the metaprogramming chapter. when i try to use it with
irb i get this error:
nomethoderror: undefined method '[]=] for nil:class
from path/dwemthy.rb:18:in 'life'
from path/dwemthy.rb:16:in 'life'
from path/rabbit.rb:4
here's the code for dwemthy.rb:
class Creature
# get a metaclass for this class
def self.metaclass; class << self; self; end; end
# advanced metaprogramming cord for clean traits
def self.traits( *arr )
return @traits if arr.empty?
# 1. setup accessors for each variable
attr_accessor *arr
# 2. add a new class method to each trait
arr.each do |a|
metaclass.instance_eval do
define_method( a ) do |val|
@triats ||= {}
@traits[a] = val
end
end
end
# 3. for each monster, the 'initialize' method should use
# the default number for each trait
class_eval do
define_method( :initialize ) do
self.class.traits.each do |k,v|
instance_varable_set("@#{k}", v)
end
end
end
end
# creature attributes are read only
traits :life, :strength, :charisma, :weapon
# this method applies a hit taken during a fight
def hit( damage )
p_up = rand( charisma )
if p_up % 9 == 7
@life += p_up / 4
puts "[#{ self.class } magick powers up #{ p_up }!]"
end
# this method takes one turn in a fight
def fight( enemy, weapon )
if life <= 0
puts "[#{ self.class } is too dead to fight!]"
return
end
# attack opponent
your_hit = rand( strength + weapon )
puts "[You hit with #{ your_hit } points of damage!]"
enemy.hit( your_hit )
# retaliation
p enemy
if enemy.life > 0
enemy_hit = rand( eneme.strenght + enemy.weapon )
puts "[Your enemy hit with #{ enemy_hit } points \
of damage!] "
self.hit( enemy_hit )
end
end
end
end
class DwemthysArray < Array
alias _inspect inspect
def inspect; "#<#{ self.class }#{ _inspect }>"; end
def method_missing( meth, *args )
answer = first.send( meth, *args )
if first.life <= 0
shift
if empty?
puts "[Whoa. You decimated Dwemty's Array!]"
else
puts "[Get ready. #{ first.class } has emerged.]"
end
end
answer || 0
end
end
to use through the metaprogramming chapter. when i try to use it with
irb i get this error:
nomethoderror: undefined method '[]=] for nil:class
from path/dwemthy.rb:18:in 'life'
from path/dwemthy.rb:16:in 'life'
from path/rabbit.rb:4
here's the code for dwemthy.rb:
class Creature
# get a metaclass for this class
def self.metaclass; class << self; self; end; end
# advanced metaprogramming cord for clean traits
def self.traits( *arr )
return @traits if arr.empty?
# 1. setup accessors for each variable
attr_accessor *arr
# 2. add a new class method to each trait
arr.each do |a|
metaclass.instance_eval do
define_method( a ) do |val|
@triats ||= {}
@traits[a] = val
end
end
end
# 3. for each monster, the 'initialize' method should use
# the default number for each trait
class_eval do
define_method( :initialize ) do
self.class.traits.each do |k,v|
instance_varable_set("@#{k}", v)
end
end
end
end
# creature attributes are read only
traits :life, :strength, :charisma, :weapon
# this method applies a hit taken during a fight
def hit( damage )
p_up = rand( charisma )
if p_up % 9 == 7
@life += p_up / 4
puts "[#{ self.class } magick powers up #{ p_up }!]"
end
# this method takes one turn in a fight
def fight( enemy, weapon )
if life <= 0
puts "[#{ self.class } is too dead to fight!]"
return
end
# attack opponent
your_hit = rand( strength + weapon )
puts "[You hit with #{ your_hit } points of damage!]"
enemy.hit( your_hit )
# retaliation
p enemy
if enemy.life > 0
enemy_hit = rand( eneme.strenght + enemy.weapon )
puts "[Your enemy hit with #{ enemy_hit } points \
of damage!] "
self.hit( enemy_hit )
end
end
end
end
class DwemthysArray < Array
alias _inspect inspect
def inspect; "#<#{ self.class }#{ _inspect }>"; end
def method_missing( meth, *args )
answer = first.send( meth, *args )
if first.life <= 0
shift
if empty?
puts "[Whoa. You decimated Dwemty's Array!]"
else
puts "[Get ready. #{ first.class } has emerged.]"
end
end
answer || 0
end
end