1

I work on a structure of classes to realize a cli script.
And I would like create class method to register a command. When a register a command, I want automatically generate a getter for this.

So, I have this structure :

lib/my_lib/commands.rb
lib/my_lib/commands/setup_command.rb

And then content of file :

# lib/my_lib/commands.rb
method MyLib
  method Commands

    def self.included(base)
      base.extend(ClassMethods)
    end

    module ClassMethods
      def register_command(*opts)
        command = opts.size == 0 ? {} : opts.extract_options!
        ...
      end

      def register_options(*opts)
        options = opts.size == 0 ? {} : opts.extract_options!
        ...
      end
    end

    class AbstractCommand
      def name
        ...
      end

      def description
        ...
      end

      def run
        raise Exception, "Command '#{self.clas.name}' invalid"
      end
    end

  end
end
# lib/my_lib/commands/setup_command.rb
module MyLib
  module Commands
    class SetupCommand < AbstractCommand
      include MyLib::Commands

      register_command :name        => "setup",
                       :description => "setup the application"

      def run
        puts "Yeah, my command is running"
      end

    end
  end
end

That I want :

# my_cli_script

#!/usr/bin/env ruby
require 'my_lib/commands/setup_command'

command = MyLib::Commands::SetupCommand.new
puts command.name # => "setup"
puts command.description # => "setup the application"
puts command.run # => "Yeah, my command is running"
1
  • 1
    Above in your code, did you by any means mean "module MyLib" instead of "method MyLib"? Also, optionally, you might have to unlearn Java to be more efficient Ruby coder :) I don't know if it's just me, or if Javaisms smell here :) Commented Sep 26, 2012 at 22:51

1 Answer 1

1

I'd do it somehow like this:

class CommandDummy

  def self.register_command(options = {})
    define_method(:name)        { options[:name] }
    define_method(:description) { options[:name] }
  end

  register_command :name        => "setup",
                   :description => "setup the application"

  def run
    puts "Yeah, my command is running"
  end
end

c = CommandDummy.new
puts c.name          # => "setup"
puts c.description   # => "setup the application"

add:

Instead of opts.size == 0 you might use opts.empty?

edit:

Just played a bit

# NOTE: I've no idea where to use stuff like this!
class CommandDummy
  # Add methods, which returns a given String
  def self.add_method_strings(options = {})
    options.each { |k,v| define_method(k) { v } }
  end

  add_method_strings :name        => "setup",
                     :description => "setup the application",
                     :run         => "Yeah, my command is running",
                     :foo         => "bar"
end

c = CommandDummy.new
puts c.name          # => "setup"
puts c.description   # => "setup the application"
puts c.run           # => "Yeah, my command is running"
puts c.foo           # => "bar"
Sign up to request clarification or add additional context in comments.

1 Comment

I admire you for not being lazy to actually write the Ruby way of doing it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.