Closed sumofparts closed 8 years ago
I agree that having unduly long names (to prevent name collisions) is a problem.
I don't think that namespacing using Ruby modules is a good idea, due to ambiguity between static vs dynamic scoping.
Here's why in code:
We would expect the following to resolve bar
.
module A
class Bar < BinData::Record ; end
module B
class Foo < BinData::Record
bar: baz
end
end
end
Now the ambiguous case. What is the desired way to resolve bar
?
prototype = nil
module A
class Bar << BinData::Record ; end
prototype = BinData::Struct.new(:fields => [:bar, :baz])
end
module B
class Bar << BinData::Record ; end
prototype.new ## should we use A::Bar or B::Bar?
end
This is ambiguous for the reader.
I'll think on a better way to design this, as I agree that this is an issue.
Let me know if this works for you.
Add an import
keyword that behaves similarly to endian
.
Type names in BinData are in a flat namespace. Ruby modules are disregarded. This eliminates the incidence of name conflicts (due to scoping) at the expense of requiring a longer name.
The endian
keyword allows the user a shortcut to shorten the name of a type. e.g. endian :little
allows a user to specify int16
instead of int16le
.
The proposed import
keyword allows the user to shorten the name of a type. While endian
shortens the end of the name, import
will shorten the beginning.
class MyNsA < BinData::Record ; end
class MyNsB < BinData::Record ; end
class MyNsMyRecord < BinData::Record
import :my_ns
a :field1 # resolved via the import shortcut
my_ns_b :field2 # fully qualified name
end
This proposal continues to ignore Ruby modules, to prevent problems with mixing static and dynamic scoping. The namespace of a BinData type remains encoded into the class name.
I think this would work quite nicely for my needs. Would 'prefix' perhaps be a more semantically helpful name vs 'import'?
Implemented in 02786d7
The keyword is search_prefix
. This allows searching multiple, prioritised namespaces.
class MyRecord < BinData::Record
search_prefix :ns1, :ns2
a :field1 # searches for ns1_a then ns2_a
end
I have an issue with namespacing that I'd love to get some advice on.
It would appear that the registry implemented in
lib/bindata/registry.rb
truncates the namespace of anything being registered to simply the rightmost portion of the namespace. For example, if I have:The record is registered as just
bar
, rather thanfoo_bar
. I realize this might be for reasons of brevity. After all, referencingbar
in a subsequent record is much more convenient than referencingfoo_bar
. However, in projects with a lot of record classes, it forces unduly long class names for the record classes to avoid collisions in the registry.Would it be acceptable to treat the parent namespace for a record definition as a 'working namespace' such that record definitions would be stored with a fully namespaced path in the registry, but could be referenced by adjacent record definitions with the currently used (rightmost) name?
Further: perhaps anything subclassing BinData::Primitive would be available globally, but anything subclassing BinData::Record would need to share the same parent namespace.
What I have in mind:
Thanks for your consideration. I'd be happy to take a stab at implementing this if it would fall within the goals of the library.