I want to use structs within my classes to save on memory, but I want my code to be easily used by others.
Say I want to use a new Struct, name it "KE". I want this Struct to be only visible from within a class I, that would be use it. I.e., if anyone who uses my code defines elsewhere class/struct "KE", it won't override my "KE", and mine won't override theirs. Having it in the same code text file is good too.
1 Answer
You can put your code into a module which will act as a namespace, e.g.:
module Foo
KE = Struct.new(:name)
# remaining code
end
Within the Foo namespace you can refer to the struct just via KE, e.g.:
module Foo
# ...
def self.build_ke(name)
KE.new(name)
end
end
Foo.build_ke('abc')
#=> #<struct Foo::KE name="abc">
Outside of Foo however, you have to use the Foo:: prefix:
Foo::KE.new('def')
#=> #<struct Foo::KE name="def">
Other KE constants won't interfere with your KE:
KE = :top_level
module Bar
KE = :nested_in_bar
end
KE #=> :top_level
Bar::KE #=> :nested_in_bar
Foo::KE #=> Foo::KE # <- your struct
To "hide" the struct, you could make the constant private via private_constant:
module Foo
KE = Struct.new(:name)
private_constant :KE
def self.build_ke(name)
KE.new(name)
end
end
Foo.build_ke #=> #<struct Foo::KE name="abc">
Foo::KE #=> NameError: private constant Foo::KE referenced
Or you could use an anonymous struct by not assigning it to a constant in the first place, e.g. via a private class method:
module Foo
def self.ke_class
@ke_class ||= Struct.new(:name)
end
private_class_method :ke_class
def self.build_ke(name)
ke_class.new(name)
end
end
Foo.build_ke('abc') #=> #<struct name="abc">
Foo.ke_class #=> NoMethodError: private method `ke_class' called for Foo:Module
1 Comment
user1134991
Hi. That's almost exactly what I need, definitely doable. So, congrats. However, if there a way to make KE invisible to other bits of the code (from different files), it would be ideal. Thanks again.
Struct::newdoes nothing more than dynamically generate a class at runtime, so aStructuses exactly as much memory as a class would. In fact, some Ruby implementations are not capable of optimizing dynamically generated classes in the same way they optimize statically created ones, so depending on which implementation you use, aStructmay even use more memory than a class.