Class arguments (newbe question)

Hello to the list!

I have the following code which prints the ip's from fail2ban.log and puts then in an array:

- --------------------------
class ReadIPs
  attr_accessor :ip
  def initialize(ip)
    @ip = ip
  end
  
  def ip(filename)
    ips = []
    File.read(filename).lines.to_a.each do |place|
      sf = 0
      while sfn = place.index(/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/,sf)
        sf = sfn + 3
        ips << $&
      end
    end
      return ips
  end
end

# print methods

a = ReadIPs.new("/Users/atma/Projects/ZoneReport/log/fail2ban.log")
puts a.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

- ---------------------------------

What I don't understand is why do I need to give the argument to the new instance of ReadIPs.new class. In my view the code should look like:

a = ReadIPs.new
puts a.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")
- ----------------------------------

But this returns an error and does not run. Can someone please drop a few light here please :slight_smile:

best regards & thanks in advance

Panagiotis (atmosx) Atmatzidis

email: atma@convalesco.org
URL: http://www.convalesco.org
GnuPG ID: 0xFC4E8BB4
gpg --keyserver x-hkp://pgp.mit.edu --recv-keys 0xFC4E8BB4
- --
The wise man said: "Never argue with an idiot. They bring you down to their level and beat you with experience."

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello to the list!

I have the following code which prints the ip's from fail2ban.log and puts then in an array:

- --------------------------
class ReadIPs
attr_accessor :ip
def initialize(ip)
@ip = ip
end

When you define an initialize method that receives an argument, you
must pass an argument when you create an instance with new.

def ip(filename)
ips =
File.read(filename).lines.to_a.each do |place|
sf = 0
while sfn = place.index(/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/,sf)
sf = sfn + 3
ips << $&
end
end
return ips
end
end

# print methods

a = ReadIPs.new("/Users/atma/Projects/ZoneReport/log/fail2ban.log")
puts a.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

- ---------------------------------

What I don't understand is why do I need to give the argument to the new instance of ReadIPs.new class. In my view the code should look like:

a = ReadIPs.new
puts a.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

Then you can remove the initialize method from the ReadIPs class. In
fact, if that's the only thing you are going to do, you don't even
need a to be an instance. You can have a class method instead, since
you are not maintaining state:

class ReadIPs
  def self.ip(filename)
  ...
  end
end

and call it like

ReadIPs.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

Another possibility is to maintain the calculated array of matched IPs
in an instance, so what I would do in that case is:

class ReadIPs
  attr_reader :ips

  def initialize file_name
    @ips = perform the algorithm to match the ips.
  end
end

and then you can do:

a = ReadIPs.new("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

which will calculate the ips and store them in the instance variable.
Then you can call:

a.ips

which will return the stored array.

Hope this helps,

Jesus.

···

On Sat, Dec 5, 2009 at 10:17 AM, Panagiotis Atmatzidis <atma@convalesco.org> wrote:

It helped a lot! Thank you for the prompt & detailed answer

Panagiotis (atmosx) Atmatzidis

email: atma@convalesco.org
URL: http://www.convalesco.org
GnuPG ID: 0xFC4E8BB4
gpg --keyserver x-hkp://pgp.mit.edu --recv-keys 0xFC4E8BB4

···

On 05 Δεκ 2009, at 11:55 π.μ., Jesús Gabriel y Galán wrote:

On Sat, Dec 5, 2009 at 10:17 AM, Panagiotis Atmatzidis > <atma@convalesco.org> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello to the list!

I have the following code which prints the ip's from fail2ban.log and puts then in an array:

- --------------------------
class ReadIPs
attr_accessor :ip
def initialize(ip)
   @ip = ip
end

When you define an initialize method that receives an argument, you
must pass an argument when you create an instance with new.

def ip(filename)
   ips =
   File.read(filename).lines.to_a.each do |place|
     sf = 0
     while sfn = place.index(/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/,sf)
       sf = sfn + 3
       ips << $&
     end
   end
     return ips
end
end

# print methods

a = ReadIPs.new("/Users/atma/Projects/ZoneReport/log/fail2ban.log")
puts a.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

- ---------------------------------

What I don't understand is why do I need to give the argument to the new instance of ReadIPs.new class. In my view the code should look like:

a = ReadIPs.new
puts a.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

Then you can remove the initialize method from the ReadIPs class. In
fact, if that's the only thing you are going to do, you don't even
need a to be an instance. You can have a class method instead, since
you are not maintaining state:

class ReadIPs
def self.ip(filename)
...
end
end

and call it like

ReadIPs.ip("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

Another possibility is to maintain the calculated array of matched IPs
in an instance, so what I would do in that case is:

class ReadIPs
attr_reader :ips

def initialize file_name
   @ips = perform the algorithm to match the ips.
end
end

and then you can do:

a = ReadIPs.new("/Users/atma/Projects/ZoneReport/log/fail2ban.log")

which will calculate the ips and store them in the instance variable.
Then you can call:

a.ips

which will return the stored array.

Hope this helps,

--
The wise man said: "Never argue with an idiot. They bring you down to their level and beat you with experience."