Announcement

Collapse
No announcement yet.

Another VM bug?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Another VM bug?

    Hi folks,

    I've been working on a project that involves custom handling for dropdown menus that have only one option, and I think I've found another Miva Script bug related to objects, or maybe arrays. (I say "another" because I recall some odd behavior where a variable's value gets destroyed in some cases when you reference it in the VALUE part of an MvASSIGN.)

    I was using this conditional to find out whether the attribute had only one option:
    Code:
    <!mvt:if expr="(NOT len(l.settings:attribute:options[2]:code))">
    I was getting weird results, and after much head-scratching and putting in debugging messages, I found that executing this statement was causing a second element to be created in the attribute:options array. I changed the conditional to this:
    Code:
    <mvt:if expr="miva_array_elements(l.settings:attribute:options) EQ 1">
    and it worked correctly: an attribute with only one option would continue to have only one option.

    Admittedly, the first conditional was not the most elegant way to test for the existence of a second array element. But still, I can't see any reason why it should actually modify the value of the attribute:options array. I understand that the len(x) function involves converting the value of x to a string. But that conversion should be done within the len() function; it shouldn't actually change the value of x. Or am I missing something?

    Thanks --
    Kent Multer
    Magic Metal Productions
    http://TheMagicM.com
    * Web developer/designer
    * E-commerce and Miva
    * Author, The Official Miva Web Scripting Book -- available on-line:
    http://www.amazon.com/exec/obidos/IS...icmetalproducA

    #2
    The virtual machine has two sets of instructions for accessing array/structure members. One set (elem/memb) will create the aggregate elements if they did not previously exist, and the other (elem_ro, memb_ro) will not. The compiler currently does not use the _ro instructions when resolving function parameters, so your call to len() created the second element. The compiler *does* use the _ro operations in normal conditional statements, so if you had used ISNULL l.settings:attribute:options[2]:code the element would not have been created. Of course, you could also have used miva_element_exists to do the test as well.

    Comment


      #3
      Hi Burch, thanks for the explanation. What about expressions in other types of tags, such as MvASSIGN, MvEVAL, etc.? Does the VM use the read-only handling for those, as well as for MvIF?
      Kent Multer
      Magic Metal Productions
      http://TheMagicM.com
      * Web developer/designer
      * E-commerce and Miva
      * Author, The Official Miva Web Scripting Book -- available on-line:
      http://www.amazon.com/exec/obidos/IS...icmetalproducA

      Comment


        #4
        I stumbled on this bug in Storemorph a few years ago. Under some conditions, the process of testing a variable value creates the variable. So subsequent calls to test for the variable may yield invalid results. I recall there was some historical compatibility reason it had not been fixed. I'd have to search for the posting, but I'm not sure those reasons are still valid. (IMHO) this should corrected.

        Jon's answer above provides a more detail explanation on the mechanics so thanks for that.

        In short, as Jon said, (ISNULL variable_name) is the prefered conditional test in the compiler and Storemorph. I've not had the problem since I dropped using Len().
        Ray Yates
        "If I have seen further, it is by standing on the shoulders of giants."
        --- Sir Isaac Newton

        Comment


          #5
          Hi Ray, Yes, I remember some of that. Ironically, I stopped using ISNULL because of a similar-but-opposite problem. I found that, if you clear a variable by setting it to emtpy-string, it still has a value, and ISNULL will return 0 for it. So I thought len() was more reliable, until now ...

          I agree that the VM has a few behaviors that really should be fixed. I think one of the reasons for not fixing them is that there might be some code out there that relies on these quirks, perhaps without the authors even realizing it, and changing the VM might result in bugs popping up.

          Also, I'll put in a vote for some sort of MvDEASSIGN command to actually un-set a variable's value, putting it back to the ISNULL state. Ditto for a miva_member_delete() with behavior similar to the existing miva_array_delete().

          Thanks --
          Kent Multer
          Magic Metal Productions
          http://TheMagicM.com
          * Web developer/designer
          * E-commerce and Miva
          * Author, The Official Miva Web Scripting Book -- available on-line:
          http://www.amazon.com/exec/obidos/IS...icmetalproducA

          Comment


            #6
            It's hard to say what would break if this were fixed. Perhaps it could be fixed but only when compiled under the next version or later. There are other VM commands that fall back to legacy behaviors.

            My biggest Wish list item would be in Storemorph

            <mvt:assign name="l.settings:array[expression]:member" value="expression" />
            <mvt:assign name="l.settings:array:member[expression]" value="expression" />

            OR

            <mvt:assign name="l.settings:array" index="expression" member="varname" value="expression" />
            <mvt:assign name="l.settings:array" member="varname" index="expression" value="expression" />

            Ray Yates
            "If I have seen further, it is by standing on the shoulders of giants."
            --- Sir Isaac Newton

            Comment

            Working...
            X