On Friday, April 10, 2015 at 1:50:31 PM UTC-5, Tom Limoncelli wrote:
>
> On Wed, Apr 8, 2015 at 9:21 AM, jcbollinger <john.bo...@stjude.org 
> <javascript:>> wrote: 
> > Are you saying that all the tests pass on Ruby 1.9, but some fail on 
> Ruby 
> > 1.8.7? 
> > 
> > I'm not sufficiently familiar with the module to quite understand the 
> > details of the test failures, but it looks like the sort order you are 
> > trying to apply does not very effectively cover the space of keys it may 
> be 
> > used to sort.  In particular, what order is supposed to be used when the 
> > bind_address does not start with a dotted-quad IP address?  Some order 
> will 
> > fall out from your code, but there's plenty of room for 
> > implementation-defined behavior there. 
>
> John, 
>
> Yes, that's exactly the problem.  The addresses that don't start with 
> dotted-quad IP addresses "fall out" one way in Ruby 1.8.7 and a 
> different order in Ruby 1.9+.  Each is stable, but different. 
>
>

So you understand the problem, and you seem to understand most of the 
needed elements of Ruby well enough to use them to solve the problem.  I 
guess you're asking for some Ruby-fu to pull it all together.

You're already generating a compound search key (although it's not strictly 
necessary for what you're doing so far); a reasonable solution would be a 
compound sort key that captures the IP address (if any) as the first part, 
and the rest of the hash key as a second part.  Here's a way to approach it 
with the help of a Ruby regex:

<%
require 'ipaddr'
if @bind
  @bind.sort_by { |address_port, bind_params|
    md = /^((\d+)\.(\d+)\.(\d+)\.(\d+))?(.*)/.match(address_port)
    [ (md[1] ? md[2..5].inject(0){ |addr, octet| (addr << 8) + octet.to_i } 
: -1), md[6] ]
  }.map do |address_port, bind_params|
-%> 
   bind <%= address_port -%> <%= Array(bind_params).join(" ") %> 
<%
  end
else
-%> 


In the sort_by() block, variable 'md' captures the match data for matching 
the given regex against the 'address_port' string.  The regex will match 
any string; the important part is the capturing groups.  If the string 
starts with a dotted-quad address then the whole address is captured as 
group 1, and the segments are captured as groups 2 - 5.  Whatever is not 
matched as a dotted-quad address is always captured as group 6.  The 
dotted-quad match is all-or-nothing; either four segments will be captured 
or none.  The sort key is then formed as a two-element array: the first 
element is -1 if no address is given, else the 4-byte integer IP address, 
and the second element is the string tail.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/80f67e99-53fe-4cf4-9319-ff4f18b8c141%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to