Array redefinition problem

(Leslie Viljoen) #1

Hello!

I have a large program which needs to be able to use Postgres OR MySQL.
Since the MySQL module's query result has a num_rows method and Postgres
returns an array, I thought I'd just redefine Array like this:

class Array
def num_rows
   return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments (0
for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
  def num_rows
    return length
  end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what else
can
cause this error?

Les

···

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

(Robert) #2

Leslie Viljoen wrote:

Hello!

I have a large program which needs to be able to use Postgres OR
MySQL. Since the MySQL module's query result has a num_rows method
and Postgres returns an array, I thought I'd just redefine Array like
this:

class Array
def num_rows
   return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments
(0 for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
  def num_rows
    return length
  end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what
else can
cause this error?

My guess is that it's unrelated to your change of the Array class. Did
you check line 443 of core.rb?

    robert

(Reyn Vlietstra) #3

heh, daars min afrikaaners op ruby-talk :slight_smile:

Why dont you use one of the db wrappers, like dbi ?
Have you seen active_record ?

···

On 8/12/05, Leslie Viljoen <leslie@camary.co.za> wrote:

Hello!

I have a large program which needs to be able to use Postgres OR MySQL.
Since the MySQL module's query result has a num_rows method and Postgres
returns an array, I thought I'd just redefine Array like this:

class Array
def num_rows
   return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments (0
for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
  def num_rows
    return length
  end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what else
can
cause this error?

Les

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

--
Reyn Vlietstra

(David Vallner) #4

Citát Leslie Viljoen <leslie@camary.co.za>:

Hello!

I have a large program which needs to be able to use Postgres OR MySQL.
Since the MySQL module's query result has a num_rows method and Postgres
returns an array, I thought I'd just redefine Array like this:

class Array
def num_rows
   return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments (0
for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
  def num_rows
    return length
  end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what else
can
cause this error?

Les

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

If the Array redefinition is nested in a module, you are shadowing the builtin
Array class with a locally defined one. Try:

  class ::Array
    # Redefine methods.
  end

to make sure you're redefining the builtin one.

(Leslie Viljoen) #5

Robert Klemme wrote:

Leslie Viljoen wrote:

Hello!

I have a large program which needs to be able to use Postgres OR
MySQL. Since the MySQL module's query result has a num_rows method
and Postgres returns an array, I thought I'd just redefine Array like
this:

class Array
def num_rows
  return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments
(0 for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
def num_rows
   return length
end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what
else can
cause this error?
   
My guess is that it's unrelated to your change of the Array class. Did
you check line 443 of core.rb?

   robert

line 443:

@entries = Array.new

When I take Array redefinition change out, the whole program runs fine, except
that it cannot call Array.num_rows, which is what I want.

···

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

(Leslie Viljoen) #6

Reyn Vlietstra wrote:

heh, daars min afrikaaners op ruby-talk :slight_smile:

heh. van waaraf is jy?

Why dont you use one of the db wrappers, like dbi ?
Have you seen active_record ?

Hm, maybe a good idea. Although I do actually want to
solve this problem. Quite often with Ruby I get strange
errors and end up spending a lot of time commenting
large blocks of code out to try and narrow them dDoes anyone know of a
program that can underown.
My pet peeve is the "syntax error" on the last line of
code - meaning I have missed an "end" somewhere.

···

On 8/12/05, Leslie Viljoen <leslie@camary.co.za> wrote:

Hello!

I have a large program which needs to be able to use Postgres OR MySQL.
Since the MySQL module's query result has a num_rows method and Postgres
returns an array, I thought I'd just redefine Array like this:

class Array
def num_rows
  return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments (0
for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
def num_rows
   return length
end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what else
can
cause this error?

Les

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

(Leslie Viljoen) #7

david@vallner.net wrote:

Citát Leslie Viljoen <leslie@camary.co.za>:

Hello!

I have a large program which needs to be able to use Postgres OR MySQL.
Since the MySQL module's query result has a num_rows method and Postgres
returns an array, I thought I'd just redefine Array like this:

class Array
def num_rows
  return length
end
end

But in another line (@entries = Array.new) I get:

/var/www/ruby/core.rb:443:in `initialize': wrong number of arguments (0
for 2) (ArgumentError)

Now if I do the same thing in a small test program, I get no errors.
This works:

class Array
def num_rows
   return length
end
end

res = Array.new
puts res.num_rows

In the large program I am not redefining Array anywhere else - what else
can
cause this error?

Les

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

If the Array redefinition is nested in a module, you are shadowing the builtin
Array class with a locally defined one. Try:

class ::Array
   # Redefine methods.
end

to make sure you're redefining the builtin one.

It's a web script, so I never noticed this warning in a class below the
array redef:
warning: redefining Object#initialize may cause infinite loop

I had a "begin" in there that was unmatched, and a rescue several
functions later -
which was causing some real strange things.

Anyway, now that I have put the begin in the same function as the rescue,
I no longer get the error. But I still can't redefine Array - now I get:

/var/www/ruby/core.rb:22:in `num_rows': undefined local variable or
method `length' for #<#<Module:0xb65fcfec>::Array:0xb65e2c78> (NameError)

The first lines of the program are:
class ::Array
  def num_rows
    return length <--- LINE 22
  end
end

a = Array.new
puts a.num_rows

-- so how do I access ::Array.length?

···

--
ruby -e "puts 'Just another fickle programmer'"

Leslie Viljoen [leslie@camary.co.za]
Camary Consulting [http://www.camary.co.za]
Cellphone [083-6186100]
Personal web [http://mobeus.homelinux.org]

(David A. Black) #8

Hi --

···

On Fri, 12 Aug 2005, Leslie Viljoen wrote:

line 443:

@entries = Array.new

When I take Array redefinition change out, the whole program runs fine, except
that it cannot call Array.num_rows, which is what I want.

I wonder whether there's another Array class, inside a module
namespace, or something like that. I can't really puzzle it out, but
the problem could, I think, lie in that direction. Or in some kind of
name clash introduced by a library you're require'ing, maybe.

David

--
David A. Black
dblack@wobblini.net

(David Vallner) #9

Citát Leslie Viljoen <leslie@camary.co.za>:

My pet peeve is the "syntax error" on the last line of
code - meaning I have missed an "end" somewhere.

Religious indentation is your best friend, putting a comment next to an "end" to
signify what you're ending is another. Then have Emacs reindent the whole file
and finding the stray "end" shouldn't be difficult :wink:

David Vallner

(Brian Schröder) #10

It's a web script, so I never noticed this warning in a class below the
array redef:
warning: redefining Object#initialize may cause infinite loop

I had a "begin" in there that was unmatched, and a rescue several
functions later -
which was causing some real strange things.

Anyway, now that I have put the begin in the same function as the rescue,
I no longer get the error. But I still can't redefine Array - now I get:

/var/www/ruby/core.rb:22:in `num_rows': undefined local variable or
method `length' for #<#<Module:0xb65fcfec>::Array:0xb65e2c78> (NameError)

The first lines of the program are:
class ::Array
  def num_rows
    return length <--- LINE 22
  end
end

a = Array.new
puts a.num_rows

-- so how do I access ::Array.length?

class Array
  alias :num_rows :length
end

[1,2,3].num_rows #=> 3

···

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

(David Vallner) #11

Citát Leslie Viljoen <leslie@camary.co.za>:

/var/www/ruby/core.rb:22:in `num_rows': undefined local variable or
method `length' for #<#<Module:0xb65fcfec>::Array:0xb65e2c78> (NameError)

Ah wait, it seems whatever is running the web script is doing some voodoo with
namespaces - the global namespace isn't what it's supposed to be, in which case
not even the aliasing would work properly.

I'm possibly summoning the Daemon Obfuscatis here, but this should work no
matter what:

  [].class.class_eval {
    alias_method(:num_rows, :length)
  }

Feel free to confuse yourself by using module_eval, or define_method.

David Vallner

(Pit) #12

Leslie Viljoen schrieb:

Anyway, now that I have put the begin in the same function as the rescue,
I no longer get the error. But I still can't redefine Array - now I get:

/var/www/ruby/core.rb:22:in `num_rows': undefined local variable or
method `length' for #<#<Module:0xb65fcfec>::Array:0xb65e2c78> (NameError)

You can see that you don't have an Array instance, but an instance of an Array class in an anonymous module.

The first lines of the program are:
class ::Array
  def num_rows
    return length <--- LINE 22
  end
end

a = Array.new
puts a.num_rows

-- so how do I access ::Array.length?

Maybe you can show us more of the code and more than the first line of the stack backtrace.

Regards,
Pit

(David Vallner) #13

Citát Brian Schröder <ruby.brian@gmail.com>:

> It's a web script, so I never noticed this warning in a class below the
> array redef:
> warning: redefining Object#initialize may cause infinite loop
>
> I had a "begin" in there that was unmatched, and a rescue several
> functions later -
> which was causing some real strange things.
>
> Anyway, now that I have put the begin in the same function as the rescue,
> I no longer get the error. But I still can't redefine Array - now I get:
>
> /var/www/ruby/core.rb:22:in `num_rows': undefined local variable or
> method `length' for #<#<Module:0xb65fcfec>::Array:0xb65e2c78> (NameError)
>
> The first lines of the program are:
> class ::Array
> def num_rows
> return length <--- LINE 22
> end
> end
>
> a = Array.new
> puts a.num_rows
>
> -- so how do I access ::Array.length?

class Array
  alias :num_rows :length
end

[1,2,3].num_rows #=> 3

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Yup, alias does indeed seem to be a better solution here. There might be a
slight bug with namespaces of methods implemented in C or something. Try using
explicitly self.length, if only for academic purposes?

David Vallner