Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-8393

Standard Array conversions do not work on return value from tree_each function

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: PUP 5.3.3
    • Fix Version/s: PUP 5.3.5, PUP 5.4.0
    • Component/s: Functions
    • Labels:
      None
    • Template:
      PUP Bug Template
    • Sub-team:
    • Team:
      Platform Core
    • Sprint:
      Platform Core KANBAN
    • Method Found:
      Needs Assessment
    • Release Notes:
      Bug Fix
    • Release Notes Summary:
      The {{tree_each}} when called without a lambda returned an {{Iterable}} that could not be converted to an {{Array}} using the new or splat operators.
    • QA Risk Assessment:
      No Action

      Description

      I am trying to see what the tree_each function actually produces, to see how I could use it for complex tree transformations.

      I went with the simplest approach first:

      # t1.pp
       
      $hash = {
        foo => bar,
        baz => [
          quux,
          { whatsit => whosit }
        ]
      }
       
      $tree = $hash.tree_each
       
      $tree_array = Array($tree)
      notice(inline_template('<% require "pp"; pp @tree_array %>'))
      

      The result was less than helpful:

      $ puppet apply t1.pp
      Error: Evaluation Error: Error while evaluating a Function Call, super: no superclass method `to_a' for #<Puppet::Pops::Types::Iterable::DepthFirstTreeIterator:0x0000000314be98>
      Did you mean?  to_s at /home/vagrant/t1.pp:13:15 on node localhost
      

      Next, I tried something Henrik Lindberg suggested:

      # t2.pp
       
      $hash = {
        foo => bar,
        baz => [
          quux,
          { whatsit => whosit }
        ]
      }
       
      $tree = $hash.tree_each
       
      $tree_array = *$tree
      notice(inline_template('<% require "pp"; pp @tree_array %>'))
      

      This gave me:

      $ puppet apply t2.pp
      [#<Puppet::Pops::Types::Iterable::DepthFirstTreeIterator:0x000000043feea0
        @containers_t=
         #<Puppet::Pops::Types::PVariantType:0x00000003451598
          @types=
           [#<Puppet::Pops::Types::PArrayType:0x00000003211df0
             @element_type=#<Puppet::Pops::Types::PAnyType:0x00000003204b00>,
             @size_type=nil>,
            #<Puppet::Pops::Types::PHashType:0x00000003211850
             @key_type=#<Puppet::Pops::Types::PAnyType:0x00000003204b00>,
             @size_type=nil,
             @value_type=#<Puppet::Pops::Types::PAnyType:0x00000003204b00>>,
            #<Puppet::Pops::Types::PObjectType:0x00000002c15de8
             @annotations=nil,
             @attributes={},
             @checks=nil,
             @equality=nil,
             @equality_include_type=true,
             @functions={},
             @name=nil,
             @parent=nil>]>,
        @current_path=[],
        @element_t=nil,
        @include_refs=false,
        @indexer_stack=[],
        @recursed=false,
        @root={"foo"=>"bar", "baz"=>["quux", {"whatsit"=>"whosit"}]},
        @value_stack=[{"foo"=>"bar", "baz"=>["quux", {"whatsit"=>"whosit"}]}],
        @with_containers=true,
        @with_root=true,
        @with_values=true>]
      Notice: Scope(Class[main]):
      Notice: Compiled catalog for localhost
      

      Again, not very useful.

      I tried passing the results of the * operator to the Array conversion...

      # t3.pp
       
      $hash = {
        foo => bar,
        baz => [
          quux,
          { whatsit => whosit }
        ]
      }
       
      $tree = $hash.tree_each
       
      $tree_array = Array(*$tree)
      notice(inline_template('<% require "pp"; pp @tree_array %>'))
      

      and got the same as the first attempt:

      $ puppet apply t3.pp
      Error: Evaluation Error: Error while evaluating a Function Call, super: no superclass method `to_a' for #<Puppet::Pops::Types::Iterable::DepthFirstTreeIterator:0x00000004b52878>
      Did you mean?  to_s at /home/vagrant/t3.pp:13:15 on node localhost
      

      Finally, I used a map to convert it to itself:

      # t4.pp
       
      $hash = {
        foo => bar,
        baz => [
          quux,
          { whatsit => whosit }
        ]
      }
       
      $tree = $hash.tree_each
       
      $tree_array = $tree.map |$idx,$val| { [ $idx, $val ] }
      notice(inline_template('<% require "pp"; pp @tree_array %>'))
      

      and this gave something useful:

      $ puppet apply t4.pp
      [[0, [[], {"foo"=>"bar", "baz"=>["quux", {"whatsit"=>"whosit"}]}]],
       [1, [["foo"], "bar"]],
       [2, [["baz"], ["quux", {"whatsit"=>"whosit"}]]],
       [3, [["baz", 0], "quux"]],
       [4, [["baz", 1], {"whatsit"=>"whosit"}]],
       [5, [["baz", 1, "whatsit"], "whosit"]]]
      Notice: Scope(Class[main]):
      Notice: Compiled catalog for localhost
      

      Henrik Lindberg told me to submit a ticket, so here I am.

        Attachments

          Activity

            People

            Assignee:
            thomas.hallgren Thomas Hallgren
            Reporter:
            JohnsonEarls Johnson Earls
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Zendesk Support