Argument types

F

Florian Kaufmann

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
 
M

Michael Neumann

Florian said:
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?

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
 
P

Pascal J. Bourguignon

Florian Kaufmann said:
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.
#!/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?

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.
 
Y

Yossef Mendelssohn

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

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

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?
 
C

Charles Johnson

Am I right?
((((((((((((((((yes, you are.)))))))))))))))

---
Charles Johnson
Advanced Computing Center for Research and Education
Vanderbilt University
(e-mail address removed)
Office: 615-343-2776
Cell: 615-478-8799
 
F

Florian Kaufmann

An index is always a natural number. It is required to be either a Fixnumor
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
 
R

Robert Dober

((((((((((((((((yes, you are.)))))))))))))))
you certainly mean
('('('('('('('('('('('('('('(' yes you are! <close them yourself, will you?=;)
R.
--=20
Si tu veux construire un bateau ...
Ne rassemble pas des hommes pour aller chercher du bois, pr=E9parer des
outils, r=E9partir les t=E2ches, all=E9ger le travail=85 mais enseigne aux
gens la nostalgie de l=92infini de la mer.

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

Gary Wright

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,796
Messages
2,569,645
Members
45,364
Latest member
CrypttoTaxSofttware

Latest Threads

Top