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.
精彩评论