1

Ruby 和 OO 很新。研究教科书,以及谷歌在雷神上找到的所有文章。

我让 Thor 努力捕获多个命令行参数和选项。不过,我想从 Cli < Thor 类之外进行其余的编程,并且无法从 Cli 类之外访问命令行参数。

问题:

Q1。Cli < Thor 类是否可以像任何其他 ruby​​ 类一样对待,或者从 Thor 继承或“Cli.start”命令是否会削弱 Cli 类的某些功能而不是不使用 Thor?问是因为我可能根本不知道如何从不使用初始化方法的类外部访问实例变量。Thor不会让我使用initialize方法来引入命令行变量,可能是因为initialize是ruby中的一个保留方法名。

Q2。如何从 Thor 类外部访问命令行参数变量 a 和 b?

这是我的代码

#!/usr/bin/env ruby

require 'thor'

class Cli < Thor
  attr_reader :a, :b
  method_option :add, :type => :string, :desc => 'add servers'
  method_option :prod, :type => :string, :desc => 'production stack'

  desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
  def tier(a,b)
    @a = a
    @b = b
    puts a
    puts b
  end
end

Cli.start

arguments = Cli.new

puts "the first argument is #{arguments.a}"

这是结果。关闭(也许)。没有错误,但 arguments.a 为零。

$ ./create.rb tier a b
a
b
the first argument is 

--

puts arguments.tier.a

抛出错误:

./create.rb:11:in `tier': wrong number of arguments (0 for 2) (ArgumentError)
    from ./create.rb:23:in `<main>'

以下工作没有 Thor 并使用初始化方法和 attr_reader,直接来自教科书。虽然无法弄清楚如何从非初始化方法访问变量。

#!/usr/bin/env ruby

class Cli 
  attr_reader :a, :b
  def initialize(a,b)
    @a = a
    @b = b
  end
end

arguments = Cli.new("a","b")

puts arguments.a

输出:

$ ./create_wo_thor.rb    
a
4

2 回答 2

1

实例化你的Cli类没有多大意义;这不是 Thor 的设计方式。

您有几个选项可以从班级外部访问内部数据。如果您只想访问几个变量,将它们存储为类变量并通过 getter(和 setter,如果您需要的话)使它们可用:

require 'thor'

class Cli < Thor
  method_option :add, :type => :string, :desc => 'add servers'
  method_option :prod, :type => :string, :desc => 'production stack'

  desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
  def tier(a,b)
    @@a = a
    @@b = b
    puts a
    puts b
  end

  def self.get_a
    @@a
  end

  def self.get_b
    @@b
  end
end

Cli.start

puts "the first argument is #{Cli.get_a}"

这如您所愿:

$ ./thor.rb 层 ab                                                                                                                                                                                                   
一个                                                                                                                                                                                                                                           
b                                                                                                                                                                                                                                           
第一个论点是

我更喜欢以下内容,使用全局哈希:

require 'thor'

$args = {}

class Cli < Thor
  method_option :add, :type => :string, :desc => 'add servers'
  method_option :prod, :type => :string, :desc => 'production stack'

  desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
  def tier(a,b)
    $args[:a] = a
    $args[:b] = b
    puts a
    puts b
  end
end

Cli.start

puts "the first argument is #{$args[:a]}"

最后,我会疏忽没有指出所有命令行参数都可以在 global 中使用ARGV,无论如何:

require 'thor'

class Cli < Thor
  method_option :add, :type => :string, :desc => 'add servers'
  method_option :prod, :type => :string, :desc => 'production stack'

  desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
  def tier(a,b)
    puts a
    puts b
  end
end

Cli.start

puts "The first argugment is #{ARGV[1]}"

最好的方法取决于您打算如何使用它。如果您只想对命令行参数进行原始访问,那ARGV就是要走的路。如果您想在 Thor 为您完成一些处理后访问某些部分,前两个中的一个可能会更有帮助。

于 2013-04-25T21:36:10.370 回答
0

这是我的代码,其中包含用于从 Cli < Thor 类外部访问命令行参数的所有三个选项。赞美达山。

#!/usr/bin/env ruby

require 'thor'
$args = {}

class Cli < Thor
  attr_reader :a, :b
  method_option :add, :type => :string, :desc => 'add servers'
  method_option :prod, :type => :string, :desc => 'production stack'

  desc "tier <stack folder name> <app | web>", "creates an app or web server tier for the stack"
  def tier(a,b)
    # store a and b in a global hash
    $args[:a] = a
    $args[:b] = b
    # store a and b in class variables 
    @@a = a
    @@b = b
  end

  # getter methods, for access of the class variables from outside the class
  def self.get_a
    @@a
  end
  def self.get_b
    @@b
  end
end

Cli.start

# three ways now to access the command line arguments from outside the Cli < Thor class
puts "the first argument, from $args[:a], is #{$args[:a]}"
puts "the second argument, from Cli.get_b, is #{Cli.get_b}"
puts "the first argument, from ARGV[1], is #{ARGV[1]}"

结果:

$ ./create.rb tier a b
the first argument, from $args[:a], is a
the second argument, from Cli.get_b, is b
the first argument, from ARGV[1], is a
于 2013-04-25T22:40:27.007 回答