Argument types


#1

The documentation of the standard classes/methods never mention of
what type/class an argument must be. For example let’s look at the
subscript of an Array. There is the form “array[index]”. But of what
Type must the index object be?
The ruby book tells me that programming ruby, types doesn’t matter so
much, what matters is to what messages an object responds. Thus I
tried the following, thinking that to_i is needed so an object can be
used as an subscript index.

#!/usr/bin/ruby
class C
def to_i
0
end
end
c = C.new
a = [0,1,2]
p a[c]

It doesn’t work however:

./test:12:in `[]’: can’t convert C into Integer (TypeError)
from ./test:12

So to which messages must C respond so objects of it can be used as
array index?

Flo


#2

Florian K. wrote:

class C
./test:12:in `[]’: can’t convert C into Integer (TypeError)
from ./test:12

So to which messages must C respond so objects of it can be used as
array index?

An index is always a natural number. It is required to be either a
Fixnum or
Bignum. You can’t pass arbitrary object to those methods. Why not:

p a[c.to_i] ?

Regards,

Michael


#3

Florian K. removed_email_address@domain.invalid writes:

The documentation of the standard classes/methods never mention of
what type/class an argument must be. For example let’s look at the
subscript of an Array. There is the form “array[index]”. But of what
Type must the index object be?
The ruby book tells me that programming ruby, types doesn’t matter so
much, what matters is to what messages an object responds. Thus I
tried the following, thinking that to_i is needed so an object can be
used as an subscript index.

Indeed, it would be nice if the arguments “duck type” was documented.

It doesn’t work however:

./test:12:in `[]’: can’t convert C into Integer (TypeError)
from ./test:12

So to which messages must C respond so objects of it can be used as
array index?

In this case, probably it’s not the result of a given method that is
used to index the array, but the argument itself! So you are probably
expected to give integers as arguments, and no visible message is sent.

You would have to check the sources of ruby.

But let’s make a thought experiment, let’s implement Array.at using
Memory and Integer:

(class Array

(def initialize( … )
(@size = …)
(@addressOfArray = (Memory.allocate @size))
self
end)

(def addressOf(index)
(@addressOfArray + index)
end)

(def at(index)
(if (> 0 index)
(index = (@size - index))
end)
(if (> 0 index)
nil
elsif (<= @size index)
nil
else
(Memory.load (self . addressOf index))
end)
end)

end)

Basically, the index should behave as an integer, but in this
pseudo-implementation it is not sent any message. It is passed as
argument to Integer.+, Integer.-, Integer.>, Integer.<= ; perhaps
these methods send some message to the index object, you’d have to
check Ruby sources to know. Perhaps they only use the identity of
the argument to let the processor compute the result, without sending
any message.


#4

Yay! Pascal’s back! And just when I was suffering from parenthesis
withdrawal.

On Apr 14, 11:00 am, removed_email_address@domain.invalid (Pascal J. Bourguignon)
wrote:

(class Array
(def at(index)
(if (> 0 index)
Woah, what?
(index = (@size - index))
end)
(if (> 0 index)
nil
elsif (<= @size index)
nil
else
(Memory.load (self . addressOf index))
You missed out on an opportunity for addresOf(index) there. Just
thought you should know.
end)
end)

end)

Basically, the index should behave as an integer, but in this
pseudo-implementation

Pseudo- is right. I’m not sure what language this is. It has some sort
of Ruby feeling, but there are far too many parentheses. Also, some
comparisons are done in a totally whacked-out fashion involving insane
ordering. I’m willing to bet the person who wrote this code doesn’t
actually know or care about Ruby, but is really some delusional Lisp
lover who harbors a deep resentment towards all languages that are not
“pure enough”.

Am I right?


#5

On Apr 14, 2009, at 11:13 AM, Yossef M. wrote:

Am I right?


-yossef

((((((((((((((((yes, you are.)))))))))))))))


Charles J.
Advanced Computing Center for Research and Education
Vanderbilt University
removed_email_address@domain.invalid
Office: 615-343-2776
Cell: 615-478-8799


#6

An index is always a natural number. It is required to be either a Fixnum or
Bignum. You can’t pass arbitrary object to those methods.

It seems that it is more complex than that. This works

%w(a b c)[1.2]

Why not:
p a[c.to_i] ?

Because I’d like to understand what I can do in general with ruby. I’d
like to be able to read the ruby doc and know for each of all those
hundred of methods what exactly I can pass as argument.

Flo


#7

On 2009-04-14, Florian K. removed_email_address@domain.invalid wrote:

The ruby book tells me that programming ruby, types doesn’t matter so
much, what matters is to what messages an object responds. Thus I
tried the following, thinking that to_i is needed so an object can be
used as an subscript index.

#to_i is not sufficient, but #to_int is:

$ irb
irb(main):001:0> foo = Object.new
=> #Object:0xb7c14064
irb(main):002:0> [ 34, 45 ][foo]
TypeError: can’t convert Object into Integer
from (irb):2:in `[]’
from (irb):2
irb(main):003:0> def foo.to_int ; 1 ; end
=> nil
irb(main):004:0> [ 34, 45 ][foo]
=> 45

Regards,

Jeremy H.


#8

On Tue, Apr 14, 2009 at 6:22 PM, Charles J.
removed_email_address@domain.invalid wrote:

On Apr 14, 2009, at 11:13 AM, Yossef M. wrote:

Am I right?


-yossef

((((((((((((((((yes, you are.)))))))))))))))
you certainly mean
(’(’(’(’(’(’(’(’(’(’(’(’(’(’(’ yes you are! <close them yourself, will
you?>
:wink:
R.

Si tu veux construire un bateau …
Ne rassemble pas des hommes pour aller chercher du bois, préparer des
outils, répartir les tâches, alléger le travail… mais enseigne aux
gens la nostalgie de l’infini de la mer.

If you want to build a ship, don’t herd people together to collect
wood and don’t assign them tasks and work, but rather teach them to
long for the endless immensity of the sea.


#9

On Apr 14, 2009, at 1:10 PM, Florian K. wrote:

An index is always a natural number. It is required to be either a
Fixnum or
Bignum. You can’t pass arbitrary object to those methods.

It seems that it is more complex than that. This works

%w(a b c)[1.2]

Because Float#.to_int is defined, although I’m not quite sure why.

This caused me to notice:

Float#ceil to greater (or equal) integer
Float#floor to smaller (or equal) integer

Float#to_int floor but towards towards zero (i.e. smaller abs value)
-0.5.to_int == 0, 0.5.to_int == 0
-0.6.to_int == 0, 0.6.to_int == 0

Float#round rounds away from zero:
-0.5.round == -1, 0.5.round == 1