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.