-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Differences in accessing ENUM-IDs between Ruby and Java. #552
Differences in accessing ENUM-IDs between Ruby and Java. #552
Comments
I think the best thing to do would be to change how Ruby handles ENUMs and make them work exactly as those generated for Java. Currently, two low-level hashes are used per ENUM, one mapping decimals to symbols and one providing the inverse of the first. The problem with that approach is that those hashes don't provide any methods, so anyone using either of both needs to use them bei their name and that breaks if borders of classes are crossed. If some ENUM would be some object instead, one could simply access its methods like in Java:
As Ruby seems to support nested classes, that shouldn't be too difficult to achieve? I guess the two hashes currently used individually should only be moved to some inner class and methods added that do what directly accessing the ENUM-hashes did currently. Should even all target languages implement ENUMs as objects only to avoid differences like I have with Java vs. Ruby? Looks like things are handled very differently depending on the target currently. I'm still looking for other alternatives a bit as well. |
It seems I have an easier workaround, qualifying the used constant with its parent class seems to be enough already:
vs.
Seems the following lines in the compiler need to be changed to fully qualify the ENUM with the first pieces of
I'll try to provide a PR tomorrow. That raises another question I already had in mind: How is requiring classes from other files handled in Ruby? The above most likely only works because
|
"enumToInt" didn't take the fully qualified path of an ENUM into account when rendering usage of the associated inverse map. If that map needed to be accessed in some external KSY compared to where the map is hosted, things failed because the map was wrongly assumed to be in the KSY where it is used. This commit changes "I__ENUM" to "Class::I__ENUM" following what has been available already as "enumDirectMap". This fixes kaitai-io/kaitai_struct#552.
"enumToInt" didn't take the fully qualified path of an ENUM into account when rendering usage of the associated inverse map. If that map needed to be accessed in some external KSY compared to where the map is hosted, things failed because the map was wrongly assumed to be in the KSY where it is used. This commit changes "I__ENUM" to "Class::I__ENUM" following what has been available already as "enumDirectMap". This fixes kaitai-io/kaitai_struct#552.
I have multiple different types in multiple different KSY-files. One of those types is managing a lot of ENUMs and most of the users of those ENUMs are contained in that type, but not all to not bloat it too much. If other types need access to elements of some external ENUM, I'm currently using
params
to simply forward the IDs of these elements. In most cases the types are so specific, that only very few IDs to forward are enough already. This way I'm actually working around the limitation that KS can't handle ENUMS in different types yet.That leads to code like the following:
[...]
That leads to working Java, but
ksv
breaks because of the following error message and generated Ruby:The mentioned constant
I__FMT_OMS_DLL_PROD_CODE
is the reverse mapping of the ENUM I'm interested in and which is contained in the external typeoms_rec
. That type is properly imported in KSY as well, else things wouldn't compile most likely.But I don't see any
require
-statements or else in the generated ruby. Things are easy for Java because you model ENUMs as classes there which simply have the attributeid
, so no need to import anything or cross classes using some static, class-level globals or such. But my KSY seems to be correct in the end, it only doesn't work because of differences in the generated code of target languages.Any idea how to handle my use case?
The text was updated successfully, but these errors were encountered: