Let's say in Java, I have class CryptoFormat, which has a static method named getLegacyFormat(). When I want to use the method, I just need to call CryptoFormat.getLegacyFormat(). This is clear because I know where the method comes from.
In Go, there is no static method. I don't really want to just make a file called crypto_format.go and define the method there. The reason is that whenever I need the method, I just call GetLegacyFormat(), which doesn't contain the context where the method comes from.
I could think of two ways to solve the problem:
Make a separate package named cryptoformat, and define the method as a global function in the package. This way, I need to make a new package for just few methods. Also, whenever I need static methods like this, I have to define new packages.
Define a struct named cryptoFormat containing method GetLegacyFormat(). Also, define a global public variable named CryptoFormat, which points to an instance of struct cryptoFormat. This way, I can call CryptoFormat.GetLegacyFormat() when I need the method.
I am not sure which one is better, or whether there is better way.
I would say option 1 you mention is the more idiomatic way to define such functions, if they don't need any state that would warrant to tie them to an underlying struct.
If there is some state you'd like to have as context for the function, then option 2 would be the way to go.
Note that in Go, functions are "first class citizens", so you don't have Java's constraints of needing to define a class for static methods.
And yes, if you want a separate namespace you'd need to define separate packages (just as in Java you'd need to define separate classes and/or packages).
If you want your implementation to be idiomatic, I'd suggest you take a look at Go's standard libraries (pick a few packages and explore how they implement their functions) to get a better feeling of the usual ways to structure this.
whenever I need the method, I just call GetLegacyFormat(), which doesn't contain the context where the method comes from.
So add context to the function name.
GetLegacyCryptoFormat()
Related
In object-oriented languages like C++ you don't have to call the base constructor. I don't understand why I need to do it in a psuedo object-oriented language like javascript. My base constructor has virtual elements that need to be setup before I call it. Constructors worked fine in ES5, why ruin them with this restriction. This error is garbage, it should be removed.
In C++ the compiler creates code to call the base constructor for you before your derived class constructor is called. Your C++ derived class definition can specify which base constructor to call and what to pass it (if there is a choice).
That's how the C++ specification is written. See short explanation here.
Javascript ES6 classes do not work the exact same way. You have to insert a place in your code where the base constructor is called with super(...) and you can specify or compute the parameters to pass to the base constructor.
In both C++ and Javascript, you can't access your own instance methods or properties before the base constructor has been called.
FYI, Java is even more restrictive than Javascript. You must put a call to super() or this() as the first statement of your constructor. Javascript at least lets you put logic that doesn't use this before calling the constructor.
In your Javascript, you can't stop this error without rewriting your code to work a different way. It's not an error you can disable.
There are valid OOP reasons (whether you agree with them or not) to not allow references to an object until all base classes have been fully initialized. Or, you can go back to the pre-ES6 way of initializing objects where there are no controls on how you do things and you can do whatever you want.
If you show us your code and explain what you're trying to do, we can likely suggest a different design that solves your problem and does not have this issue.
Is lib a special keyword for Frogatto Formula Language (FFL)? That seems to be the way of invoking class methods. For example:
where frog = lib.citadel.create_creature('Giant Frog')
Also, I am interested to know where can I find a list of all the available lib.**** library objects and how to list of all their available functions.
I wouldn't call it a keyword as such, more a symbol that appears in the standard namespace. As such it is functionally fairly close to a keyword.
When you create a class by adding a file e.g. data/classes/blah.cfg then a singleton instance of this class will be available using lib.blah. This is a convenient way of effectively creating your own namespace of functions -- create a class, add functions to it, then your functions can be accessed using lib.classname.functionname()
I'm writing a function that iterates over the methods on a given struct and binds the methods to handlers. I would like to skip over internal methods if possible. I'm not sure if this is possible to do so explicitly - I reviewed the documentation for the reflect package and I didn't see a means to detect if a given Value is an internal method. I know I can get the method's name, and then check if it starts with a lowercase character but I'm not sure if there's a kosher way to accomplish this. It's also possible that the internal / public boundary really only exists at compile time anyways, so there really isn't even a way of knowing this beyond the method's name. In either case I'd like to know for sure. Thanks!
The reflect package will not give you unexported methods via Type.Method. Pretty much, if you can see it via reflect, it is already exported.
See https://play.golang.org/p/61qQYO38P0
According to the documentation for EventMachine.watch_file the handler argument has to be a Module (or a class inheriting from EventMachine::FileWatch). Why is it designed this way? For me a block (or Proc) argument would be more natural and flexible (since it allows to use local variables via closure)...
The docs are not super clear, but you can also supply a sub-class of FileWatch. That would let you use locals more easily.
It takes either a module with the needed methods, or a class with the needed methods AND it must be a sub-class of the desired class.
Take a look at the code, specifically, the klass_from_handler method.
I want to get a variable's class type in freemarker, used var.class.simpleName;
but if var is a Map, freemarker will process class as a key to find value in var.
it throw exception. how can I do this ? thanks for any suggestion.
First I have to ask why do you need that, because FreeMarker templates aren't supposed to know even if var is Map at all. Maybe your data-model is not what the template needs.
Anyway, for now, I would write a custom TemplateMethodModelEx for this purpose, something that you can use like ${classOf(var)}. Inside the TemplateMethodModelEx implementation you will receive a TemplateModel as the argument value, and then you can check if it's an AdapterTemplateModel, and if so you can get back the original object and get its class. (If it's not a AdapterTemplateModel, then it perhaps isn't even a wrapped Java object, so it doesn't make sense to ask what the class of the original object is.) However, the DefaultObjectWrapper with incompatibleImprovements set to less than 2.3.22 doesn't give AdapterTemplateModel to wrapped Map-s... so in 2.3.21 you will still have to use BeansWrapper, but you can at least set simpleMapWrapper to true.
In 2.3.22 it will be actually possible to write ${var?api.class}... you might use the nightly build. Though it only supposed to solve the problem where you can't access business methods because the primary type of the business class is Map.