鉴于下面的Java代码,你可以在Ruby类中代表这两个static final
变量的最接近的代码是什么?并且,在Ruby中是否可以区分private static
和public static
变量,就像在Java中一样?
public class DeviceController
{
...
private static final Device myPrivateDevice = Device.getDevice("mydevice");
public static final Device myPublicDevice = Device.getDevice("mydevice");
...
public static void main(String args[])
{
...
}
}
答案 0 :(得分:44)
答案 1 :(得分:3)
我能想到的最终变量是将变量作为模块的实例变量:
class Device
# Some static method to obtain the device
def self.get_device(dev_name)
# Need to return something that is always the same for the same argument
dev_name
end
end
module FinalDevice
def get_device
# Store the device as an instance variable of this module...
# The instance variable is not directly available to a class that
# includes this module.
@fin ||= Device.get_device(:my_device).freeze
end
end
class Foo
include FinalDevice
def initialize
# Creating an instance variable here to demonstrate that an
# instance of Foo cannot see the instance variable in FinalDevice,
# but it can still see its own instance variables (of course).
@my_instance_var = 1
end
end
p Foo.new
p (Foo.new.get_device == Foo.new.get_device)
输出:
#<Foo:0xb78a74f8 @my_instance_var=1>
true
这里的技巧是通过将设备封装到模块中,您只能通过该模块访问设备。从类Foo
开始,无法直接修改您正在访问的设备,而无需直接对Device
类或FinalDevice
模块执行操作。 freeze
FinalDevice
中的Foo
电话可能适合或不适合,具体取决于您的需求。
如果您想制作公共和私人访问者,可以像这样修改class Foo
include FinalDevice
def initialize
@my_instance_var = 1
end
def get_device_public
get_device
end
private
def get_device_private
get_device
end
private :get_device
end
:
FinalDevice::get_device
在这种情况下,您可能还需要修改@fin
以获取参数。
更新:@banister指出FinalDevice
中声明的Foo
确实可以由Foo#inspect
的实例访问。我懒得假设,因为它不在Foo
的默认文本输出中,所以它不在@fin
内。
您可以通过更明确地使FinalDevice
成为class Device
def self.get_device(dev_name)
dev_name
end
end
module FinalDevice
def get_device
FinalDevice::_get_device
end
protected
def self._get_device
@fin ||= Device.get_device(:my_device).freeze
end
end
class Foo
include FinalDevice
def get_device_public
get_device
end
def change_fin
@fin = 6
@@fin = 8
end
private
def get_device_private
get_device
end
private :get_device
end
f = Foo.new
x = f.get_device_public
f.change_fin
puts("fin was #{x}, now it is #{f.get_device_public}")
模块的实例变量来解决此问题:
fin was my_device, now it is my_device
哪个正确输出:
{{1}}
答案 2 :(得分:1)
class DeviceController
MY_DEVICE = Device.get_device("mydevice")
end
是的,require 'device'
如果需要的话。
虽然没有什么可以阻止你在其他地方重新定义常量,除了警告:)
答案 3 :(得分:0)
Ruby中的私有静态:
class DeviceController
@@my_device = Device.get_device("mydevice")
end
Ruby中的public static:
class DeviceController
def self.my_device; @@my_device; end
@@my_device = Device.get_device("mydevice")
end
Ruby没有'final':)