Golf on CLI code

I

Intransition

I have a registry (array) of CLI classes. Each class has a class
method cli() that returns an array of strings or regular expressions
to match against ARGV to see if it is the chosen cli. Eg.

class FooList << CLIBase
def self.cli ; ['foo', 'list'] ; end
...
end

So if someone puts on the command line:

$ foo list

Then the above class would match for it. I wrote the algorithm to
handle this, but I think it's Ugh-ly. Wondering if the smart folk here
might play a game of golf on it.

def command(argv)
lookup = registry.map{ |cc| [cc, cc.cli] }.sort{ |a,b| b[1].size
<=> a[1].size }
x = lookup.find do |cc, cli|
t = true
cli.each_with_index do |r, i|
t = t && (r === argv)
end
t
end
cmdc = x[0]
argv = argv[x[1].size..-1]
return cmdc, argv
end
 
J

Joel VanderWerf

Intransition said:
def command(argv)
lookup = registry.map{ |cc| [cc, cc.cli] }.sort{ |a,b| b[1].size
<=> a[1].size }
x = lookup.find do |cc, cli|
t = true
cli.each_with_index do |r, i|
t = t && (r === argv)
end
t
end
cmdc = x[0]
argv = argv[x[1].size..-1]
return cmdc, argv
end


Untested:

def command(argv)
lookup = registry.sort_by {|cc| cc.cli.size}
cmdc = lookup.find do |cc|
cc.cli.zip(argv).all? do |r,arg|
r === arg
end
end
return cmdc, argv[cmdc.cli.size..-1]
end

The following (assuming it works!) would be more compact still:

class Symbol
alias old_to_proc to_proc
def to_proc
case self
when :=== # etc.
proc {|x,y| x === y}
else
old_to_proc
end
end
end

def command(argv)
lookup = registry.sort_by {|cc| cc.cli.size}
cmdc = lookup.find do |cc|
cc.cli.zip(argv).all?(&:===)
end
return cmdc, argv[cmdc.cli.size..-1]
end
 
M

Martin DeMello

=A0 def command(argv)
=A0 =A0 =A0lookup =3D registry.map{ |cc| [cc, cc.cli] }.sort{ |a,b| b[1].= size
<=3D> a[1].size }

at the least this should be registry.map {|cc| [cc, cc.cli]}.sort_by
{|a| -a[1].size}

also, you're never using cc, so why carry it around?

lookup =3D registry.map {|cc| cc.cli}.sort_by {|cli| -cli.size}

and using the ever-handy symbol.to_proc

lookup =3D registry.map(&:cli).sort_by(&:size).reverse
=A0 =A0 =A0x =3D lookup.find do |cc, cli|
=A0 =A0 =A0 =A0t =3D true
=A0 =A0 =A0 =A0cli.each_with_index do |r, i|
=A0 =A0 =A0 =A0 =A0t =3D t && (r =3D=3D=3D argv)
=A0 =A0 =A0 =A0end
=A0 =A0 =A0 =A0t
=A0 =A0 =A0end


# untested
lookup.find do |cli|
cli.zip(argv).inject(true) {|e, (i, j)| e && (i =3D=3D=3D j)}
end
=A0 =A0 =A0cmdc =3D x[0]
=A0 =A0 =A0argv =3D argv[x[1].size..-1]
=A0 =A0 =A0return cmdc, argv
=A0 =A0end

martin
 
I

Intransition

Thanks Joel and Martin. Amazingly concise answers -- it's amazes me
sometimes how small a piece of code can get in Ruby :)

I haven't gotten back to the particular code I need this for yet which
is why I haven't responded until now, but should be back to it soon
and I'll let you know how it worked out.
 
W

w_a_x_man

  def command(argv)
     lookup = registry.map{ |cc| [cc, cc.cli] }.sort{ |a,b| b[1].size
<=> a[1].size }

at the least this should be registry.map {|cc| [cc, cc.cli]}.sort_by
{|a| -a[1].size}

also, you're never using cc, so why carry it around?

lookup = registry.map {|cc| cc.cli}.sort_by {|cli| -cli.size}

and using the ever-handy symbol.to_proc

lookup = registry.map(&:cli).sort_by(&:size).reverse
     x = lookup.find do |cc, cli|
       t = true
       cli.each_with_index do |r, i|
         t = t && (r === argv)
       end
       t
     end


# untested
lookup.find do |cli|
  cli.zip(argv).inject(true) {|e, (i, j)| e && (i === j)}
end


lookup.find{|cli| cli == argv[0,cli.size] }

     cmdc = x[0]
     argv = argv[x[1].size..-1]
     return cmdc, argv
   end

martin
 
W

w_a_x_man

  def command(argv)
     lookup = registry.map{ |cc| [cc, cc.cli] }.sort{ |a,b| b[1].size
<=> a[1].size }
at the least this should be registry.map {|cc| [cc, cc.cli]}.sort_by
{|a| -a[1].size}
also, you're never using cc, so why carry it around?
lookup = registry.map {|cc| cc.cli}.sort_by {|cli| -cli.size}
and using the ever-handy symbol.to_proc
lookup = registry.map(&:cli).sort_by(&:size).reverse
     x = lookup.find do |cc, cli|
       t = true
       cli.each_with_index do |r, i|
         t = t && (r === argv)
       end
       t
     end

# untested
lookup.find do |cli|
  cli.zip(argv).inject(true) {|e, (i, j)| e && (i === j)}
end

lookup.find{|cli|  cli == argv[0,cli.size] }


That won't work if cli contains a regexp.

lookup.find{|cli|  cli.zip(argv).all?{|a,b| a == b }
 
W

w_a_x_man

  def command(argv)
     lookup = registry.map{ |cc| [cc, cc.cli] }.sort{ |a,b|b[1].size
<=> a[1].size }
at the least this should be registry.map {|cc| [cc, cc.cli]}.sort_by
{|a| -a[1].size}
also, you're never using cc, so why carry it around?
lookup = registry.map {|cc| cc.cli}.sort_by {|cli| -cli.size}
and using the ever-handy symbol.to_proc
lookup = registry.map(&:cli).sort_by(&:size).reverse
     x = lookup.find do |cc, cli|
       t = true
       cli.each_with_index do |r, i|
         t = t && (r === argv)
       end
       t
     end
# untested
lookup.find do |cli|
  cli.zip(argv).inject(true) {|e, (i, j)| e && (i === j)}
end

lookup.find{|cli|  cli == argv[0,cli.size] }

That won't work if cli contains a regexp.

lookup.find{|cli|  cli.zip(argv).all?{|a,b| a == b }


Should be

lookup.find{|cli|  cli.zip(argv).all?{|a,b| a === b }}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top