Why is my method not found? (NoMethodError)

Discussion in 'Ruby' started by anansi, May 7, 2007.

  1. anansi

    anansi Guest

    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
    anansi, May 7, 2007
    #1
    1. Advertising

  2. anansi

    Evan Light Guest

    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 #####################
    Evan Light, May 7, 2007
    #2
    1. Advertising

  3. anansi

    Evan Light Guest

    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.
    Evan Light, May 7, 2007
    #3
  4. anansi

    anansi Guest

    Evan Light wrote:
    > 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
    anansi, May 7, 2007
    #4
  5. anansi

    John Joyce Guest


    >
    > 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.
    John Joyce, May 7, 2007
    #5
  6. anansi

    zswu Guest

    It's a good habit that just writed *end* after you had writen "class,
    def, if, do, e.t.c" before code the segment.
    --
    /***********************************/
    Lets go With the float....
    /***********************************/
    zswu, May 8, 2007
    #6
  7. On May 7, 2007, at 7:56 PM, zswu wrote:

    > 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
    James Edward Gray II, May 8, 2007
    #7
  8. anansi

    zswu Guest

    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.

    On 5/8/07, James Edward Gray II <> wrote:
    > On May 7, 2007, at 7:56 PM, zswu wrote:
    >
    > > 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
    >
    >



    --
    /***********************************/
    Lets go With the float....
    /***********************************/
    zswu, May 8, 2007
    #8
  9. anansi

    Evan Light Guest

    On May 7, 11:31 am, anansi <> wrote:
    > EvanLightwrote:
    > > 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?


    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". ;-)
    Evan Light, May 8, 2007
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,816
    Smokey Grindel
    Dec 2, 2006
  2. anon1m0us
    Replies:
    2
    Views:
    214
    anon1m0us
    Feb 6, 2007
  3. Replies:
    2
    Views:
    115
  4. Alex Shulgin
    Replies:
    4
    Views:
    204
    Alex Shulgin
    Sep 16, 2007
  5. Sukeerthi Adiga

    NoMethodError: private method `to_date'

    Sukeerthi Adiga, Feb 25, 2008, in forum: Ruby
    Replies:
    11
    Views:
    393
    P. mark Anderson
    Jul 24, 2008
Loading...

Share This Page