Skip to main content
Inspiring
November 22, 2010
Question

StructGet vs. Evaluate - Getting different results

  • November 22, 2010
  • 2 replies
  • 1903 views

I'm working on a project that involves using PDF forms and I am trying to dynamically grab an element in the pdf form. I use StructFindKey to find the form element. Then I tried using StructGet to specifically grab the element using the path provided by StructFindKey. But what I'm seeing is that StructGet isn't finding the element whereas if I use Evaluate I do get the element. Instead StructGet is essentially overwriting the element and creating a new empty structure for its value. (The element is an array of values, so it's easy to see that StructGet is replacing it.) This is using CF 8.

<cfpdfform action="read" source="#request.path.file##attributes.fileid#.pdf" result="frmStruct"></cfpdfform>
<cfset tst = StructFindKey(frmStruct,"EF153", "all")>
<cfdump var="#tst#">
<cfset tst3 = Evaluate("frmStruct#tst[1].path#")>
<cfdump var="#tst3#">
<cfset tst2 = StructGet("frmStruct#tst[1].path#")>
<cfdump var="#tst2#">

Am I just misunderstanding what StructGet does?

    This topic has been closed for replies.

    2 replies

    Inspiring
    November 22, 2010

    Do you need to access the relevant element by its dotted path?  structFindValue() does provide the "owner" reference for you, which is the relevant element.  Why not just reference it that way?

    I've never used structGet() (never found a need to), but it behaves rather strangely to me.  Look at this code:

    <cfset st = {
        outer =    {
            mid    = {
                inner1  = "value",
                inner2    = {a=1,b=2}
            }
        }
    }>
    <cfdump var="#st#" label="st">
    <hr />

    <cfset theWholeStruct = structGet("st")>
    <cfdump var="#theWholeStruct#" label="theWholeStruct">
    <cfdump var="#st#" label="st">
    <hr />

    <cfset theSubStruct = structGet("st.outer.mid")>
    <cfdump var="#theSubStruct#" label="theSubStruct">
    <cfdump var="#st#" label="st">
    <hr />

    <cfset inner1Value = structGet("st.outer.mid.inner1")><!--- this overwrites inner1 --->
    <cfdump var="#inner1Value#" label="inner1Value">
    <cfdump var="#st#" label="st">
    <hr />

    <cfset inner2Value = structGet("st.outer.mid.inner2")>
    <cfdump var="#inner2Value#" label="inner2Value">
    <cfdump var="#st#" label="st">
    <hr />

    <cfset inner3Value = structGet("st.outer.mid.inner3")><!--- this CREATES inner3 --->
    <cfdump var="#inner3Value#" label="inner3Value">
    <cfdump var="#st#" label="st">
    <hr />

    (it's nice how - on a CF forum - there is no option to apply CFML or even HTML source highlighting!)

    It all works fine until where I indicate.  I'm seeing the same as you were: it's blowing away the value at that key and replacing it with an empty struct.  However the similar subsequent call - which attempts to get a struct rather than a simple value - works fine.

    So I would say there are two bugs here:

    * structGet() should not overwrite existing values just because they're not structs

    * structGet() should not create anything.  It's structGET(), it's not structGETIFITSTHEREOTHERWISECREATEITANDGETIT()

    Obviously the second point is "documented", but it's dumb behaviour.

    I can't see how the first is anything other than a bug.

    --
    Adam

    SteveTXAuthor
    Inspiring
    November 22, 2010

    I'm inclined to agree with you that it's buggy behavior. I'm using the owner element from StructFindKey as you suggested and that is working out for me. Thanks for your response.

    Inspiring
    November 22, 2010

    Hi SteveTX,

    Well. If you look at the livedocs here,

    http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_s_23.html

    It clearly says that the "StructGet" function creates a structure (or) structures which means that we can use it for extracting any element. Also in the same document page, if you go through the "Returns" and "Usage" titles you will get to know that it has the ability to create structures to make the "pathdesired" variable as a valid path.

    HTH

    SteveTXAuthor
    Inspiring
    November 22, 2010

    I understood that StructGet would create a value if it doesn't exist, but in this case it is overwriting an existing value. For example, in my test the initial StructFindKey is returning the following path:

    .s_316.pg1.StatementTable.EF153


    If I do StructGet("frmStruct.s_316.pg1.StatementTable"), I get back the StatementTable structure which has three elements, one of which is the array EF153. But when I do StructGet("frmStruct.s_316.pg1.StatementTable.EF153") I don't get that array; I get an empty Structure and EF153 in original has been changed. I guess it's just that StructGet can only return structures and turns the element into a structure if it isn't one. Thanks for the response.