[Pharo-dev] Strange primitive failure

Eliot Miranda eliot.miranda at gmail.com
Fri Nov 1 18:43:19 EDT 2013


Hi Ben,


On Fri, Nov 1, 2013 at 7:01 AM, Benjamin <
Benjamin.VanRyseghem.Pharo at gmail.com> wrote:

> Hello guys,
>
> is it expected that
>
> 1 perform: #gcd: withArguments: {2}
> works
>
> while
>
> 1 perform: #gcd: withArguments: {2} asOrderedCollection
> fails ?
>

As Alexandre explained it's because the VM insists on an Array.  But there
is a neat way to solve this.  e.g. if the method is defined as

Object>>perform: selector withArguments: argArray
"Send the selector, aSymbol, to the receiver with arguments in argArray.
Fail if the number of arguments expected by the selector
does not match the size of argArray.
Primitive. Optional. See Object documentation whatIsAPrimitive."

<primitive: 84>
^ self perform: selector withArguments: argArray inSuperclass: self class

 and

Object>>perform: selector withArguments: argArray inSuperclass: lookupClass
"NOTE:  This is just like perform:withArguments:, except that
the message lookup process begins, not with the receivers's class,
but with the supplied superclass instead.  It will fail if lookupClass
cannot be found among the receiver's superclasses.
Primitive. Essential. See Object documentation whatIsAPrimitive."

<primitive: 100>
(selector isSymbol)
ifFalse: [^ self error: 'selector argument must be a Symbol'].
(selector numArgs = argArray size)
ifFalse: [^ self error: 'incorrect number of arguments'].
(self class == lookupClass or: [self class inheritsFrom: lookupClass])
ifFalse: [^ self error: 'lookupClass is not in my inheritance chain'].
self primitiveFailed

then redefine perform:withArguments:inSuperclass: to read something like:

Object>>perform: selector withArguments: argArray inSuperclass: lookupClass
"NOTE:  This is just like perform:withArguments:, except that
the message lookup process begins, not with the receivers's class,
but with the supplied superclass instead.  It will fail if lookupClass
cannot be found among the receiver's superclasses.
Primitive. Essential. See Object documentation whatIsAPrimitive."

<primitive: 100>
(argArray isCollection and: [argArray isSequenceable and: [argArray class
~~ Array]]) ifTrue:
[^self perform: selector withArguments: argArray asArray inSuperclass:
lookupClass].
selector isSymbol
ifFalse: [^ self error: 'selector argument must be a Symbol'].
selector numArgs = argArray size
ifFalse: [^ self error: 'incorrect number of arguments'].
(self class == lookupClass or: [self class inheritsFrom: lookupClass])
ifFalse: [^ self error: 'lookupClass is not in my inheritance chain'].
self primitiveFailed

c.f. e.g. the asInteger send in

Object>>at: index
"Primitive. Assumes receiver is indexable. Answer the value of an
indexable element in the receiver. Fail if the argument index is not an
Integer or is out of bounds. Essential. See Object documentation
whatIsAPrimitive."

<primitive: 60>
index isInteger ifTrue:
[self class isVariable
ifTrue: [self errorSubscriptBounds: index]
ifFalse: [self errorNotIndexable]].
index isNumber
ifTrue: [^self at: index asInteger]
ifFalse: [self errorNonIntegerIndex]

which allows one to write #(seriously ?) at: 1.0

HTH,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20131101/07e5c93b/attachment-0002.html>


More information about the Pharo-dev mailing list