This is the code:
class StringScanner @str = "" @kounter = 0
def initialize(str) @str = str
end
def scan(arg)
res = @str.scan(arg)
return nil unless @kounter<res.length
@kounter=@kounter+1
res[@kounter-1]
end
end
str = "Watch how I soar!"
ss = StringScanner.new(str)
loop do
word = ss.scan(/\w+/) # Grab a word at a time
break if word.nil?
puts word
sep = ss.scan(/\W+/) # Grab next non-word piece
break if sep.nil?
end
And this is the result:
C:/Documents and Settings/Roby/Desktop/Apps/Ruby/prova2.rb:9:in `scan':
undefined method `<' for nil:NilClass (NoMethodError)
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:18
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17:in `loop'
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17
You have to initialize instance members inside the initialize
function, or another function that's called after instantiation.
That's why @kounter is nil. Try putting @kounter=0 inside #initialize
HTH
MT
···
On Wed, Mar 19, 2008 at 2:38 PM, Roberto Casadei <robyonrails@katamail.com> wrote:
This is the code:
class StringScanner @str = "" @kounter = 0
def initialize(str) @str = str
end
def scan(arg)
res = @str.scan(arg)
return nil unless @kounter<res.length
@kounter=@kounter+1
res[@kounter-1]
end
end
str = "Watch how I soar!"
ss = StringScanner.new(str)
loop do
word = ss.scan(/\w+/) # Grab a word at a time
break if word.nil?
puts word
sep = ss.scan(/\W+/) # Grab next non-word piece
break if sep.nil?
end
And this is the result:
C:/Documents and Settings/Roby/Desktop/Apps/Ruby/prova2.rb:9:in `scan':
undefined method `<' for nil:NilClass (NoMethodError)
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:18
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17:in `loop'
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17
This is the code:
class StringScanner @str = "" @kounter = 0
def initialize(str) @str = str
end
def scan(arg)
res = @str.scan(arg)
return nil unless @kounter<res.length
@kounter=@kounter+1
res[@kounter-1]
end
end
str = "Watch how I soar!"
ss = StringScanner.new(str)
loop do
word = ss.scan(/\w+/) # Grab a word at a time
break if word.nil?
puts word
sep = ss.scan(/\W+/) # Grab next non-word piece
break if sep.nil?
end
And this is the result:
C:/Documents and Settings/Roby/Desktop/Apps/Ruby/prova2.rb:9:in `scan':
undefined method `<' for nil:NilClass (NoMethodError)
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:18
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17:in `loop'
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17
Help.
I'm not sure I understand Ruby at all.., but @kounter.class is 'NilClass'.
This is the code:
class StringScanner @str = "" @kounter = 0
def initialize(str) @str = str
end
def scan(arg)
res = @str.scan(arg)
return nil unless @kounter<res.length
@kounter=@kounter+1
res[@kounter-1]
end
end
str = "Watch how I soar!"
ss = StringScanner.new(str)
loop do
word = ss.scan(/\w+/) # Grab a word at a time
break if word.nil?
puts word
sep = ss.scan(/\W+/) # Grab next non-word piece
break if sep.nil?
end
And this is the result:
C:/Documents and Settings/Roby/Desktop/Apps/Ruby/prova2.rb:9:in `scan':
undefined method `<' for nil:NilClass (NoMethodError)
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:18
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17:in `loop'
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17
Help.
The probblem is in the initializing. If you explicitly initialize @kounter in the initialize method then it knows it's a Fixnum.
This is the code:
class StringScanner @str = "" @kounter = 0
Since the previous two lines are inside a class context rather than
inside an instance method, they define two class instance variables,
i.e. they are instance variables of the class object named
StringScanner.
These two variables are never actually used in the rest of the code,
much as it might seem to an untrained eye.
def initialize(str) @str = str
This creates an instance variable for the INSTANCE of StringScanner
being initialized, this is an entirely different variable than the @str we saw before.
end
def scan(arg)
res = @str.scan(arg)
return nil unless @kounter<res.length
Again @kounter is an instance variable associated with a particular
StringScanner object, it is NOT the previously seen @kounter.
@kounter=@kounter+1
res[@kounter-1]
end
end
str = "Watch how I soar!"
ss = StringScanner.new(str)
loop do
word = ss.scan(/\w+/) # Grab a word at a time
break if word.nil?
puts word
sep = ss.scan(/\W+/) # Grab next non-word piece
break if sep.nil?
end
Now even if you straighten out the two variables, you are going around
Robin Hood's barn to accomplish what can be easily done with:
"Watch how I soar!".scan(/\w+/).each {|word| puts word}
or perhaps
puts "Watch how I soar!".scan(/\w+/).join("\n")
···
On 3/19/08, Roberto Casadei <robyonrails@katamail.com> wrote:
This is the code:
class StringScanner @str = "" @kounter = 0
def initialize(str) @str = str
end
def scan(arg)
res = @str.scan(arg)
return nil unless @kounter<res.length
@kounter=@kounter+1
res[@kounter-1]
end
end
str = "Watch how I soar!"
ss = StringScanner.new(str)
loop do
word = ss.scan(/\w+/) # Grab a word at a time
break if word.nil?
puts word
sep = ss.scan(/\W+/) # Grab next non-word piece
break if sep.nil?
end
And this is the result:
C:/Documents and Settings/Roby/Desktop/Apps/Ruby/prova2.rb:9:in `scan':
undefined method `<' for nil:NilClass (NoMethodError)
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:18
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17:in `loop'
from C:/Documents and
Settings/Roby/Desktop/Apps/Ruby/prova2.rb:17
Help.
A simple way to understand how scoping (and naming convention) is working in ruby is to try the following 3 examples and note their output/errors:
1....
class C
str = "Hello"
def look
puts str.class
end
end
c = C.new
c.look
2....
class C @str = "Hello"
def look
puts @str.class
end
end
c = C.new
c.look
3...
class C
@@str = "Hello"
def look
puts @@str.class
end
end
c = C.new
c.look
Variables aren't typed in Ruby, nor are they declared. A variable
isn't a particular class, it refers to an object, and the reference
can change over the life of the program.
@a = 1 #@a is now a fix num @a = @a * 1.2 # And now it's a float @a = @a.to_s # And now it's a String
···
On 3/19/08, Slark <slark@dev.null> wrote:
The probblem is in the initializing. If you explicitly initialize @kounter in the initialize method then it knows it's a Fixnum.