Why is my method not found? (NoMethodError)

A

anansi

Hi,
I have written a small tcp scanner procedural and wanted to change it to
OOP but something went wrong. Until this line everything works fine:

my_scanner.scanning(hosts,ports)

but here I always get:
test.rb:95: private method `scanning' called for
#<Scanner:0xb7c9c428> (NoMethodError)

but why? my_scanner is from the Scanner class which owns the method
scanning?!? Do I get something wrong?

here's my code:

#!/usr/bin/ruby -w

require 'socket'
require 'timeout'


class Scanner


def initialize
@hosts,@ports = Array($*)
end



def portarrange
case @ports
when /^.+[..]/ # for
ranges (75..123)
@ports = @ports.split("..")
@ports = @ports[0].to_i..@ports[1].to_i
when /^.+[,]/ # for
multiple ports (34,345,213)
@ports = @ports.split(",")
else
@ports = Array(@ports) # for
one single port (21)
end
end



def hostarrange
case @hosts
when /^.+[,]/ # for
multiple IP's/hosts (81.95.1.40,64.111.124.251,www.cnn.com)
@hosts = @hosts.split(",")
else
@hosts = Array(@hosts) # for
one single port (81.95.1.40)
end
end


def output(state,port)
printed = false
portsfile = File.new("ports", "r")
scanpat = "^.+ #{port}/tcp"
portsfile.each_line do |line|
if line =~ Regexp.new(scanpat)
puts "#{state} : #{line}"
printed = true
end
puts "#{state} : #{port}" if printed == false end
ensure
portsfile.close
end
end

def scanning(hosts,ports)
hosts.each do |host|
begin
puts "scanning #{host}:"
ports.each do |port|
begin
Timeout::timeout(10){TCPSocket.new(host, port)} #
set timeout here
rescue Timeout::Error
output("filtered",port)
rescue
output("closed",port)
else
output("open",port)
end end
end
end
end


##################### code start #####################

puts "no arguments past,correct usage:\nruby #{$0} [hosts] [ports]\n" if
!ARGV[1]

my_scanner = Scanner.new

hosts = my_scanner.hostarrange
ports = my_scanner.portarrange
=begin
puts "debugging: "
puts hosts
puts ports
# everything alright until here
=end
my_scanner.scanning(hosts,ports)

##################### eof #####################


--
greets

(
)
(
/\ .-"""-. /\
//\\/ ,,, \//\\
|/\| ,;;;;;, |/\|
//\\\;-"""-;///\\
// \/ . \/ \\
(| ,-_| \ | / |_-, |)
//`__\.-.-./__`\\
// /.-(() ())-.\ \\
(\ |) '---' (| /)
` (| |) `
jgs \) (/


one must still have chaos in oneself to be able to give birth to a
dancing star
 
E

Evan Light

Your problem is that there is way too much nesting within your
methods. You lost track of which "end" maps to which "do" and "begin"
in numerous places. As a general rule, if you're nesting more than
two levels deep within a method, you just made your method a lot more
difficult to maintain. The below version fixes your nesting issues
(but does not correct them for maintainability).

require 'socket'
require 'timeout'

class Scanner

def initialize
@hosts,@ports = Array($*)
end

def portarrange
case @ports
when /^.+[..]/
@ports = @ports.split("..")
@ports = @ports[0].to_i..@ports[1].to_i
when /^.+[,]/
@ports = @ports.split(",")
else
@ports = Array(@ports)
end
end

def hostarrange
case @hosts
when /^.+[,]/
@hosts = @hosts.split(",")
else
@hosts = Array(@hosts)
end
end

def output(state,port)
printed = false
portsfile = File.new("ports", "r")
scanpat = "^.+ #{port}/tcp"
begin
portsfile.each_line do |line|
if line =~ Regexp.new(scanpat)
puts "#{state} : #{line}"
printed = true
end
puts "#{state} : #{port}" if printed == false
end
ensure
portsfile.close
end
end

def scanning(hosts,ports)
hosts.each do |host|
begin
puts "scanning #{host}:"
ports.each do |port|
begin
Timeout::timeout(10){TCPSocket.new(host, port)}
rescue Timeout::Error
output("filtered",port)
rescue
output("closed",port)
else
output("open",port)
end
end
end
end
end
end

##################### code start #####################

puts "no arguments past,correct usage:\nruby #{$0} [hosts] [ports]\n"
if
!ARGV[1]

my_scanner = Scanner.new

hosts = my_scanner.hostarrange
ports = my_scanner.portarrange
=begin
puts "debugging: "
puts hosts
puts ports
# everything alright until here
=end
my_scanner.scanning(hosts,ports)

##################### eof #####################
 
E

Evan Light

Sorry. Neglected to provide the literal answer to your question.
Because of the incorrect placement of "end"s, your definition of
"scanning" actually occurred within another one of your method
definitions. I hadn't tried that before but, unsurprisingly, it has
the net effect of making your "method within a method" private.
 
A

anansi

Evan said:
Sorry. Neglected to provide the literal answer to your question.
Because of the incorrect placement of "end"s, your definition of
"scanning" actually occurred within another one of your method
definitions. I hadn't tried that before but, unsurprisingly, it has
the net effect of making your "method within a method" private.

hi,
many thanks !! now I could fix it with your help (there was a further
"end"-mistake in the output routine..) but do you know any tricks or
meassures to avoid these deep nestings while coding or keep track of the
begins and ends of ones code?

--
greets

(
)
(
/\ .-"""-. /\
//\\/ ,,, \//\\
|/\| ,;;;;;, |/\|
//\\\;-"""-;///\\
// \/ . \/ \\
(| ,-_| \ | / |_-, |)
//`__\.-.-./__`\\
// /.-(() ())-.\ \\
(\ |) '---' (| /)
` (| |) `
jgs \) (/


one must still have chaos in oneself to be able to give birth to a
dancing star
 
J

John Joyce

hi,
many thanks !! now I could fix it with your help (there was a
further "end"-mistake in the output routine..) but do you know any
tricks or meassures to avoid these deep nestings while coding or
keep track of the begins and ends of ones code?
Code folding is one way. In TextMate for example, it is easy to see
if you put end in enough times.
One other thing is to put a comment after an 'end' to tell you what
it is ending.

C-like languages can be just as much trouble with closing braces.
 
Z

zswu

It's a good habit that just writed *end* after you had writen "class,
def, if, do, e.t.c" before code the segment.
 
J

James Edward Gray II

It's a good habit that just writed *end* after you had writen "class,
def, if, do, e.t.c" before code the segment.

I feel it's a much better idea to use an editor that handles that
busy work for you. It just drops the error count too much not to be
worth it.

James Edward Gray II
 
Z

zswu

Certainly, this is a good idea, though i dont use this kind of
editor.Because i want more controlling to my code, and this method
make me feelling better.It is just a personal habit, not anything
else.Everyone has own good play.
 
E

Evan Light

EvanLightwrote:

hi,
many thanks !! now I could fix it with your help (there was a further
"end"-mistake in the output routine..) but do you know any tricks or
meassures to avoid these deep nestings while coding or keep track of the
begins and ends of ones code?

The first question that I ask myself when I start to nest deeploy is
"should I be factoring some of this nested code into additional
methods". If even for the sake of my own sanity, the answer is
usually "yes". ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top