[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

newbie problem

JP

4/5/2006 2:49:00 PM


Hi, i just started to learn ruby today and run into annoying problem, i
don't quite get what's
wrong in the code snippet below, what i try to do is simple count all
"document" elements from xml file
why it complains this:

xmlreader.rb:33:in `tag_start': undefined method `+' for nil:NilClass
(NoMethodError)
from f:/ruby/lib/ruby/1.8/rexml/parsers/streamparser.rb:24:in `parse'


sum is undefined? but why? here's the code:


require "rexml/document"
include REXML

class Listener
sum=0

def text(text)
puts text
end

def xmldecl(version,encoding,standalone)
puts version
puts encoding
end

def tag_start(name,attrs)
if name == "document"
sum += 1
end
end

def tag_end(name)
end
end

list = Listener.new

xmlfile = File.new( "f:\\data2\\mloy\\out\\mtl009index.3.xml")
sparser = Parsers::StreamParser.new(xmlfile,list)

sparser.parse()
puts sum



5 Answers

Eric K Idema

4/5/2006 6:29:00 PM

0

James H. <james.herdman@gmail.com> wrote:
> Ruby doesn't define the "+=" operator. You need to say this instead:
> sum = sum + 1

Ruby does have a += operator. (It doesn't have a ++ operator, which is
probably what you were thinking of)

To the OP, if you intend for sum to be an instance variable it should be
prefixed with an '@':

@sum = 0

@sum += 1

etc. Or, consider using one of the attr methods to create accessors.


Eric

baumanj

4/5/2006 6:47:00 PM

0

James H. wrote:

> Ruby doesn't define the "+=" operator. You need to say this instead:

Sure it does:

$ irb --simple-prompt
>> sum = 0
=> 0
>> sum += 1
=> 1

It's ++ that ruby doesn't define.

> sum = sum + 1
> Or, better yet,
> sum.next

Actually, it would have to be "sum = sum.next" if you actually wanted
to update the value of sum, but there's nothing wrong with sum += 1.

The problem is scope. If you want sum to be an instance variable, you
need to define it as @sum. Also, since you can't reference instance
variables from within the class definition (they must be accessed from
an instance method), you have to declare this in the initialize method
(you could get tricky and do it conditionally in the tag_start method,
but what's the point?). Finally, to give read-only access to this
attribute from outside the class, you can use the attr_accessor macro.
Then you'll be able to access the sum attribute as list.sum. This
version should work:

require "rexml/document"
include REXML

class Listener
attr_accessor :sum

def initialize
@sum = 0
end

def text(text)
puts text
end

def xmldecl(version,encoding,standalone)
puts version
puts encoding
end

def tag_start(name,attrs)
if name == "document"
@sum += 1
end
end

def tag_end(name)
end
end

list = Listener.new

xmlfile = File.new( "f:\\data2\\mloy\\out\\mtl009index.3.xml")
sparser = Parsers::StreamParser.new(xmlfile,list)

sparser.parse()
puts list.sum

baumanj

4/5/2006 6:49:00 PM

0

Dang. I was too slow.

James Herdman

4/5/2006 7:00:00 PM

0

It's okay, now I'll never forget ;) *feels a little silly at the
moment*

James H.

JP

4/6/2006 5:19:00 AM

0

> This
> version should work:
>

Yep it worked perfectly, ruby seems to be bit different than other languages
i have used but also very powerful, tasks like this simple xml parsing is
pain with e.g. c++, with ruby just 4 lines of code, how cool is that!
Now to the next step, trying to add this xml stuff to database

thanks for all,

/JP