0

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.

4
  • 2
    Your question is not clear to me. Perhaps adding a code example would help? But to avoid naming collisions you usually wrap your code into modules to namespace them. Commented Jun 12, 2022 at 11:22
  • I think that you just helped me. I need to look at modules. It looks like the way to go ( I have used namespaces in TCL). I am a hardware engineer, and I am doing coding work as means to improve my productivity, therefore I have a lot of holes in my SW skillset. Thanks! Commented Jun 12, 2022 at 12:24
  • 3
    "I want to use structs within my classes to save on memory" – Struct::new does nothing more than dynamically generate a class at runtime, so a Struct uses 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, a Struct may even use more memory than a class. Commented Jun 12, 2022 at 12:53
  • Oh, good know... Commented Jun 12, 2022 at 13:02

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.