Constructing closures on the fly

Hello ruby-talk,

ok, that’s my problem: i had large list of filenames (100k strings,
for example) and need to quickly sort them based on constructed
criterion. This criterion gived by user in form of string containing
letters ‘ensgi3’, where each letter maps to expression, parameterized
by filename, so:

filenames.sort_files "en"
must be equal to
filenames.sort_by {|name| [ext(name), name(name)]}

filenames.sort_files "ges"
must be equal to
filenames.sort_by {|name| [group(name), ext(name), size(name)]}

and so on. Currently i use non-functional approach:

def sort_files(crit)
sort_by {|name| construct(crit,name)}
end

def construct(crit,name)
arr = []
crit.each_byte {|c|
case c
when ?g then arr << group(name)

end
}
arr
end

while faster approach will be:

def sort_files(crit)
sort_by convert_crit(crit)
end

Best regards,
Bulat mailto:bulatz@integ.ru

Bulat Ziganshin wrote:

Hello ruby-talk,

ok, that’s my problem: i had large list of filenames (100k strings,
for example) and need to quickly sort them based on constructed
criterion. This criterion gived by user in form of string containing
letters ‘ensgi3’, where each letter maps to expression, parameterized
by filename, so:

filenames.sort_files “en”
must be equal to
filenames.sort_by {|name| [ext(name), name(name)]}

filenames.sort_files “ges”
must be equal to
filenames.sort_by {|name| [group(name), ext(name), size(name)]}

and so on. Currently i use non-functional approach:

def sort_files(crit)
sort_by {|name| construct(crit,name)}
end

def construct(crit,name)
arr =
crit.each_byte {|c|
case c
when ?g then arr << group(name)

end
}
arr
end

while faster approach will be:

def sort_files(crit)
sort_by convert_crit(crit)
end

I think that your approach is quite OK.

The only way to create the closure on fly (and
omit the iteration in it) is by eval (not tested):

def apply_crit
a=
crit.each_byte { |b| a << {?g => group,…}[b] }
a.join(“,”)
end

eval “sort_by {|n| [#{apply_crit}] }”

Of course this is not a very good style, but may be
somewhat faster.

Regards, Christian