# Argument types

**URL:** <https://www.ruby-forum.com/t/argument-types/165507>\
**Category:** Ruby\
**Created:** [April 14, 2009, 5:30pm UTC](https://www.ruby-forum.com/t/argument-types/165507 "2009-04-14T17:30:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 5:30pm UTC](https://www.ruby-forum.com/t/argument-types/165507/1 "2009-04-14T17:30:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 5:47pm UTC](https://www.ruby-forum.com/t/argument-types/165507/2 "2009-04-14T17:47:20Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 6:00pm UTC](https://www.ruby-forum.com/t/argument-types/165507/3 "2009-04-14T18:00:52Z")

</div>

Florian K. [removed\_email\_address@domain.invalid](mailto: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.

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 6:13pm UTC](https://www.ruby-forum.com/t/argument-types/165507/4 "2009-04-14T18:13:47Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 6:23pm UTC](https://www.ruby-forum.com/t/argument-types/165507/5 "2009-04-14T18:23:09Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 7:10pm UTC](https://www.ruby-forum.com/t/argument-types/165507/6 "2009-04-14T19:10:39Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 6:45pm UTC](https://www.ruby-forum.com/t/argument-types/165507/7 "2009-04-14T18:45:27Z")

</div>

On 2009-04-14, Florian K. [removed\_email\_address@domain.invalid](mailto: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.

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 7:24pm UTC](https://www.ruby-forum.com/t/argument-types/165507/8 "2009-04-14T19:24:10Z")

</div>

On Tue, Apr 14, 2009 at 6:22 PM, Charles J.  
[removed\_email\_address@domain.invalid](mailto: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?\>  
> 😉  
> 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.

---

<div class="post-metadata">

**Author:** ![krasba](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/df705f/32.png) [@krasba](https://www.ruby-forum.com/u/krasba)\
**Post date:** [April 14, 2009, 7:40pm UTC](https://www.ruby-forum.com/t/argument-types/165507/9 "2009-04-14T19:40:04Z")

</div>

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
