从Thor类外部访问命令行参数

时间:2013-04-25 20:24:41

标签: ruby thor

Ruby和OO的新手。研究教科书,以及谷歌在托尔上发现的所有文章。

我让Thor工作以捕获多个命令行参数和选项。我想从Cli外面做其余的编程<虽然Thor类,但我无法从Cli类外部访问命令行参数。

问题:

Q1。可以Cli< Thor类可以像任何其他ruby类一样对待,或继承自Thor,或“Cli.start”命令,削弱Cli类的某些功能而不使用Thor?问,因为我可能根本不知道如何从不使用initialize方法的类外部访问实例变量。 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

outupt:

$ ./create_wo_thor.rb    
a

2 个答案:

答案 0 :(得分:1)

实例化Cli课程没有多大意义;这不是托尔的设计方式。

您可以从课外访问内部数据。如果您只想访问几个变量,将它们存储为类变量并通过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 tier a b                                                                                                                                                                                                   
a                                                                                                                                                                                                                                           
b                                                                                                                                                                                                                                           
the first argument is a

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

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]}"

最后,我不能指出所有命令行参数在全局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完成一些处理之后访问某些部分,前两个中的一个可能会更有帮助。

答案 1 :(得分:0)

这是我的代码,其中包含所有三个选项,用于从Cli&lt;之外访问命令行参数。托尔班。赞美Darshan。

#!/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