2013-04-25 75 views
1

对Ruby和OO来说很新颖。学习课本,以及谷歌在雷神发现的所有文章。从Thor类的外部访问命令行参数

我有Thor工作捕获多个命令行参数和选项。我想从Cli < Thor类之外完成其余的编程,并且无法从Cli类外部访问命令行参数。

问题:

Q1。 Cli < Thor类可以像任何其他ruby类一样处理,还是继承自Thor或“Cli.start”命令,可以削弱Cli类的某些功能而不使用Thor?询问是因为我可能根本不知道如何从不使用initialize方法的类外部访问实例变量。 Thor不会让我使用initialize方法来引入命令行变量,可能是因为initialize是ruby中的保留方法名称。 Q2302。我如何从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>' 

下没有雷神工程和使用initialize方法和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 

回答

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

最后,我会是不能不指出的是,所有的命令行参数,在全球可用,反正:

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是要走的路。如果你想托尔已经做了一些处理后,你访问某些片段,前两个中的一个可能会更有帮助。

+0

超级彻底和清晰的解释,达山。谢谢! – 2013-04-25 22:24:30

+0

非常受欢迎,保罗! – 2013-04-25 22:26:16

+0

关于ARGV仍然可用的好处!有趣的是,ARGV忽略了命令行上的方法名称。换句话说,对于./thor层中的B,ARGV [1]是“一”,而不是“层”。想知道如果托尔处理分配给ARGV []。 – 2013-04-25 22:38:24

0

这里是我的代码为包括从CLI <雷神类的外部访问的命令行参数所有三个选项。恭喜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