【问题标题】:Ruby - How share data between ClassMethod and InstanceRuby - 如何在 ClassMethod 和 Instance 之间共享数据
【发布时间】:2012-09-26 22:32:23
【问题描述】:

我致力于构建类结构以实现 cli 脚本。
我想创建类方法来注册命令。 当注册一个命令时,我想为此自动生成一个 getter。

所以,我有这个结构:

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

然后是文件内容:

# 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

我想要的:

# 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"

【问题讨论】:

  • 在您的代码中,您的意思是“module MyLib”而不是“method MyLib”吗?此外,可选地,您可能必须放弃学习 Java 才能成为更高效的 Ruby 编码器 :) 我不知道是不是只有我一个人,或者这里有 Javaisms 的味道 :)

标签: ruby class methods class-method


【解决方案1】:

我会这样做:

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"

添加:

你可以用opts.empty?代替opts.size == 0

编辑:

刚玩了一会

# 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"

【讨论】:

  • 我很佩服你不懒惰地实际编写 Ruby 方式 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 2015-08-14
  • 2019-10-19
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多