Probably bug with arraySwap()

30 views
Skip to first unread message

Adam Cameron

unread,
Aug 23, 2012, 6:57:34 PM8/23/12
to ra...@googlegroups.com
G'day
Hey, is this a bug or intended behaviour:

<cfscript>
a = ["tahi", "toru", "rua", "wha"];
a = [];
a[1] = "tahi";
a[3] = "rua";
a[4] = "wha";

writeDump(a);

arraySwap(a, 2, 3);
writeDump(a);
</cfscript>

Railo breaks on the second swap, with:

Railo 4.0.0.013 Error (expression)
Messagecan't swap values of array
DetailElement at position [2] doesn't exist in array

CF manages this all right, so I'd've thought Railo would / ought to as well.  If one can have empty array elements, array functions should be able to cope with them, yes?

--
Adam


Gert Franz

unread,
Aug 24, 2012, 6:46:27 AM8/24/12
to ra...@googlegroups.com

Actually I think CF is doing it wrong here since according to your code there is NO element with the index 2. So how to swap a non existing element with an existing one?

 

Greetings from Switzerland

Gert Franz

 

Railo Technologies      Professional Open Source

skype: gert.franz         ge...@getrailo.com

+41 76 5680 231           www.getrailo.com

Adam Cameron

unread,
Aug 24, 2012, 8:36:25 AM8/24/12
to ra...@googlegroups.com
Hi Gert, thanks for replying here.

I dunno that I agree with your assertion there: there is an element at index position 2, it's just null.

This can be borne out by looking at the underlying Vector, and having a poke around:

<cfscript>
    a = arrayNew(1);

    a[1] = "tahi";
    a[3] = "rua";
    a[5] = "rima";
    a[7] = "whitu";
    arrayDeleteAt(a, 7);    // 6th / last element is empty

    v = createObject("java", "java.util.Vector").init(a);
</cfscript>
<cfoutput>
    arrayLen(a): #arrayLen(a)#<br />    <!--- this outputs "6" because there IS an element at index point 6 --->
    v.size(): #v.size()#<br />    <!--- this outputs "6" because there IS an element at index point 6 --->

    <cfset e = v.elementAt(1)>    <!---ie: the SECOND element.  This doesn't error because there IS a second element--->
    <!---and, yeah, I get that if I go a[2] I get an error.  I think THIS is the incorrect behaviour in all this --->

    isDefined(): #isDefined("variables.e")#<br /><!---"not defined"... as we know this is how CF deals with NULL --->
    structKeyExists(): #structKeyExists(variables, "e")#<br /><!--- ditto --->

    <cftry>
        <cfset e = v.elementAt(6)><!--- (bear in mind that's the SEVENTH element... this is a Java method, so the indexes are zero-based) ie: def doesn't exist in the Vector, so demonstrates what happens when we access the element at an index that doesn't exist. Because the behaviour here is different from when we accessed the second element, it further proves that there IS a second element --->
        <!---this has errored now, so the next coupla lines don't run --->
        isDefined(): #isDefined("variables.e")#<br />
        structKeyExists(): #structKeyExists(variables, "e")#<br />
        <cfcatch>
            <cfdump var="#cfcatch#"><!--- "java.lang.ArrayIndexOutOfBoundsException: 6 >= 6 at java.util.Vector.elementAt(Vector.java:427" --->
        </cfcatch>
    </cftry>

    toString(): #a.toString()#<br /> <!---shows the nulls --->
    serializeJson(a): #serializeJson(a)#<br /> <!---shows the nulls --->
    <cfdump var="#variables#"><!--- shows the nulls (somewhat inelegantly) --->
</cfoutput>

So if I want to swap index position 2 (null) & 3 (rua), then that's exactly what I do: put a null in a[3], and put a "rua" into a[2] (obviously one of those is going to go into a temporary variable during the swap, but you get / already knew the idea).

Thoughts?

--
Adam

Michael Offner

unread,
Aug 27, 2012, 5:09:36 AM8/27/12
to ra...@googlegroups.com
i think it is not possible to say what is right and wrong here, in
CFML null does not exists, but behind the curtain it exists ;-) i can
even give you a example where a struct key with null value can be
accessed with regular cfml code.


<cffunction name="test">
<cfargument name="arg1" required="no">

<cfdump var="#arguments#">
<cfdump var="#arguments['arg1']#">
<cfdump var="#arguments.arg1#">
</cffunction>
<cfset test()>

if you run this code you will see that there is a value in the
argument scope with the key "arg1" and the value null.
even the value is null the second dump works in this case and outputs
"null" in Railo and ACF, the crazy thing is that the third dump breaks
in ACF with a "Element ARG1 is undefined in ARGUMENTS" exception, in
railo also the 3th dump works, for one simple reason, we will never
handle dot notation and bracket notation in a different way.

you see the answer is not so simple and clear here, simply because
CFML is not consistent in this behavior. we will adapt the ACF
behavior in this case, because (i think) it does not break existing
Railo Code.

/micha


2012/8/24, Adam Cameron <adamcamero...@gmail.com>:
> Hi Gert, thanks for replying here.
>
> I dunno that I agree with your assertion there: there *is *an element at
--
/micha

Michael Offner CTO Railo Technologies GmbH

Michael Offner

unread,
Aug 27, 2012, 5:10:31 AM8/27/12
to ra...@googlegroups.com
i forgot one thing, can you please raise a ticket for this

tnx micha

2012/8/27, Michael Offner <mic...@getrailo.com>:

Adam Cameron

unread,
Aug 27, 2012, 6:01:46 AM8/27/12
to ra...@googlegroups.com
Thanks for the feedback micha.

Bug raised as RAILO-2048.

--
Adam
Reply all
Reply to author
Forward
0 new messages