Ordering in each_pair

67 views
Skip to first unread message

Simon

unread,
Feb 10, 2014, 3:59:41 AM2/10/14
to puppet...@googlegroups.com
Hi,

I have read about the known "feature" of ruby 1.8.7 not using the entered order for each_pair and using some random order instead,  has anyone managed a work around for this that does not mean having to upgrade to 1.9.3 

I have hiera data that looks something like this

my::variables:
   "variable1":
        comment: '# this is a variable comment'
        value:  '100'
   "variable2":
        comment: '# this is a variable comment'
        value:  '200'
   "variable3":
        comment: '# this is a variable comment'
        value:  '300'

in my template i have

<% @vars.sort.each_list do |varname, hash | -%>
<%= hash['comment'] %>
<%= varname %> = <%= hash['value'] %>
<% end -%>

i wanted them to come out like the following but they come out in a random order so nearly every puppet run could cause a change and restart a service

# this is a variable comment
variable1 = 100
# this is a variable comment
variable2 = 200
# this is a variable comment
variable3 = 300

any ideas

cheers
Simon



jcbollinger

unread,
Feb 10, 2014, 9:30:37 AM2/10/14
to puppet...@googlegroups.com


On Monday, February 10, 2014 2:59:41 AM UTC-6, Simon wrote:
Hi,

I have read about the known "feature" of ruby 1.8.7 not using the entered order for each_pair and using some random order instead,


This is an utterly routine characteristic of such data structures.  If you want access by key, use a hash.  If you want access in order, use an array.  If you want both, use a type specially designed to support it.  I understand that Ruby 1.9 has such a type, but I think it's a different one than the standard Hash.

 
 has anyone managed a work around for this that does not mean having to upgrade to 1.9.3 

I have hiera data that looks something like this

my::variables:
   "variable1":
        comment: '# this is a variable comment'
        value:  '100'
   "variable2":
        comment: '# this is a variable comment'
        value:  '200'
   "variable3":
        comment: '# this is a variable comment'
        value:  '300'

in my template i have

<% @vars.sort.each_list do |varname, hash | -%>
<%= hash['comment'] %>
<%= varname %> = <%= hash['value'] %>
<% end -%>



I don't know what the method Array.each_list() is supposed to do, nor where your arrays obtained such a method.  However, you should be able to achieve what you want with something quite similar to the code you presented.  Something like this, perhaps:

<%  @vars.sort.each do | pair | -%>
<%=   pair[1]['comment'] %>
<%=   pair[0] %> = <%= pair[1]['value'] %>
<%  end -%>

 
i wanted them to come out like the following but they come out in a random order so nearly every puppet run could cause a change and restart a service


Hash.sort() yields the contents of the hash as an array of [ key, value ] pairs, in ascending order by key (according to the keys' types' <=> operators).  This is the natural basis for such a computation as you want to perform.

If you're not getting the expected result then I suspect the problem is different than you think.  In view of the fact that I find no documentation anywhere for an Array.each_list() or Enumerable.each_list() method in any version of Ruby, I suspect that your catalog compilation is failing when it tries to evaluate that template.  Thereafter, your agent will either apply a cached catalog or apply no catalog at all, depending on how it's configured.  Check your logs.


John

Simon

unread,
Feb 10, 2014, 11:19:15 AM2/10/14
to puppet...@googlegroups.com
Hi John,

thanks for the reply!

sorry for confusing things,  that will teach me to cut and paste without reading,  the template i pasted was from yesterday when i was testing with 1.9.3  the method i use at the moment is

<% @vars.each_pair do |varname, hash | -%>
<%= hash['comment'] %>
<%= varname %> = <%= hash['value'] %>
<% end -%>

I was sure that i tried sort.each do and had no success but on trying it again with your code it works fine.

thanks for your help

Simon
Reply all
Reply to author
Forward
0 new messages