Can't figure out what's wrong

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

here is the code for rabbit.rb:
class Rabbit < Creature
traits :bobs

life 10
strength 2
charisma 44
weapon 4
bombs 3

# little boomerang
def ^( enemy )
	fight( enemy, 13 )
end

# the hero's sword is unlimited
def /( enemy )
	fight( enemy, rand( 4+ ( ( enemy.life % 10 ) ** 2 ) ) )
end

# lettuce will build your strength and extra ruffage
# will fly in the face of your opponent
def %( enemy )
	lettuce = rand( chairsma )
	puts "[Healthy lettuce gives you#( lettuce ) life points!!]"
	@life += lettuce
	fight( enemy, 0 )
end

# bombs, but you have only threee
def *( enemy )
	if @bombs.zero?
		puts '[Out of bombs!]'
		return
	end
	@bombs -= 1
	fight( enemy, 86 )
end

end

Erik, there are some typos in your code. See below.

erik blas schrieb:

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’

This means that in line 18, you tried to call method “[]=” on nil. Nil
doesn’t have such a method, so the NoMethodError is raised.

def self.traits( *arr )
@traits[a] = val
This is line 18. It looks like an assignment, but it really is a method
call. It calls method “[]=” on the object @traits with arguments a and
val. The error message above means that @traits is nil. If you look at
the previous line (line 17), you notice the typo.

  		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)

This should be “instance_variable_set”. Note the missing “i”.

  		end
  	end
  end

end

I haven’t looked further. HTH.

Regards,
Pit

Thank you for the help. Guess I’m just tired and didn’t notice all the
typos. Was driving me up the wall.

On Tue, 27 Dec 2005 18:52:23 +0900, erik blas removed_email_address@domain.invalid
wrote:

Thank you for the help. Guess I’m just tired and didn’t notice all the
typos. Was driving me up the wall.

When typing in a program that has been provided, typos in Ruby can be
irritating, as you’ve seen.

When building my own programs, I try to go in smaller bites in Ruby than
I might
in C# or Java, because syntax errors and typos are often hard to find.