开发者

Ruby scope question, option parsing

So I'm using the awesome trollop gem to do option parsing, but I'm having a general problem with the scope of the variables it's setting.

require 'trollop'

class MyClass
  opts = Trollop::options do
    opt :thing, "does something", default: "blah", type: String
  end

  def my_method
    p开发者_StackOverflow中文版uts opts[:thing]
  end
end

But I get:

undefined local variable or method `opts' for #<MyClass:0x0000010203c840> (NameError)

Any ideas what I'm doing wrong with my scope?


There are about six options here: instance variable, class instance variable, class variable, class constant, global variable, global constant. Which to use depends on your needs.

Instance Variable - each MyClass instance gets its own options:

class MyClass
  def initialize
    @opts = ...
  end

  def my_method
    puts @opts[:thing]
  end
end

Class Instance Variable - single value across the class that can be reassigned:

class MyClass
  @opts = ...
  class << self
    attr_accessor :opts
  end

  def my_method
    puts self.class.opts[:thing]
  end
end

Class Variable - each MyClass and all subclasses share the same value (convenient syntax, but rarely a good idea):

class MyClass
  @@opts = ...
  def my_method
    puts @@opts[:thing]
  end
end

Class Constant - single object that may be mutated, but not re-assigned. Easily accessed from this class, accessible from others via MyClass::OPTS:

class MyClass
  OPTS = ...
  def my_method
    puts OPTS[:thing]
  end
end

Global Variable - you can only have one of these in your entire app; often global variables are ill-advised, but perhaps appropriate for a standalone application's options:

$opts = ...
class MyClass
  def my_method
    puts $opts[:thing]
  end
end

Global Constant - accessed from many classes, can't be set to a new value, but may be mutated:

OPTS = ...
class MyClass
  def my_method
    puts OPTS[:thing]
  end
end


Shouldn't you just use instance variable?

require 'trollop'

class MyClass
  def initialize
    @opts = Trollop::options do
      opt :thing, "does something", default: "blah", type: String
    end
  end

  def my_method
    puts @opts[:thing]
  end
end


You are defining 'opts' as a local variable inside your class. Instances methods (like my_method) will not be able to access it. Is opts supposed to be "global" for the whole class? In that case:

class MyClass
  @@opts = Trollop::options...

  def my_method
    puts @@opts[:thing]
  end
end

Or is there supposed to be a unique one for each instance of the class?

class MyClass
  def initialize
    @opts = Trollop::options...
  end

  def my_method
    puts @opts[:thing]
  end
end

This might be a good read: http://sporkmonger.com/2007/2/19/instance-variables-class-variables-and-inheritance-in-ruby


You'd want to make it either a class variable or an instance variable, depending on your needs.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜