[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

can't figure out what's wrong

erik blas

12/27/2005 6:46:00 AM

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

--
Posted via http://www.ruby-....


4 Answers

erik blas

12/27/2005 6:48:00 AM

0

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

--
Posted via http://www.ruby-....


Pit Capitain

12/27/2005 8:26:00 AM

0

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.

> 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

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


erik blas

12/27/2005 9:52:00 AM

0

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

--
Posted via http://www.ruby-....


Ronald E Jeffries

12/28/2005 2:56:00 AM

0

On Tue, 27 Dec 2005 18:52:23 +0900, erik blas <ether.sa@gmail.com> 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.

--
Ron Jeffries
www.XProgramming.com
I'm giving the best advice I have. You get to decide if it's true for you.