The Crystal Programming Language Forum

Operate on a collection, passing a Proc of mixed types?

Hello, I’m trying to sort an Array of file pathes, using different procs. But it seems to be a problem that not all the procs return value of the same type. Is there a way to handle this without blowing out the code?

Simplified example (

def mtime(path)

def sorting_method
    ->(path : String) { mtime(path) },
    ->(path : String) { -mtime(path) },
    ->(path : String) { path.downcase },

files = [] of String
files.sort_by! &sorting_method

The error:

14 | files.sort_by! &sorting_method
Error: expected a function type, not (Proc(String, Int64) | Proc(String, String))

What do you expect to happen? You could fix the primary error by casting the array entries to String -> String | Int32. But the next problem is that it results in comparing String with Int32 which obviously doesn’t work.

def mtime(path)

files = [] of String

case rand(3)
when 0 then files.sort_by! { |path| mtime(path) }
when 1 then files.sort_by! { |path| -mtime(path) }
when 2 then files.sort_by!(&.downcase)

Yes, that’s what I ended up with, but thought it was better to ask. Thanks.

I expected the sample to work. Despite the value returned by sorting_method being represented as union of types, practically it’s always consistent throughout sorting, and compare of mixed types never really happens. Apparently, the only reason the snippet doesn’t work is the compiler being unable to figure that out. Maybe that changes one day.