Is there a way to generate a constructor with the default values in it already? - android-studio

Let's say I have a class with variables that I have initialized just after the declarations in the Class scope.
Is there a shortcut or plugin to generate a constructor that sets all the values to their initial initializations or original values set in the class scope, without manually entering them?
I realize that just reinitializing the class should do it, but I need a method for a specific use case.

Related

Pass variable from a puppet class to a hiera .yaml file

does anyone know if a variable can be passed from a puppet class to a .yaml file?
class my_module::my_class () {
$current_date = '2021-10-12';
}
The objective would be to be able to obtain the value of the variable in a .yaml file
my_module::my_class::date_from_class:
I don't know if this is possible in any way.
Thanks in advance
It is possible to interpolate the value of a class variable into your Hiera data:
my_module::my_class::date_from_class: %{my_module::my_class::current_date}
But it is usually unwise to do so because class variables do not receive their values until and unless the class is evaluated. Class evaluation order is difficult to predict, and may change as the manifest set or class parameter values change.
If another class wants the value in question then it can just access the class variable directly. Although that's subject to the same caveat, at least another class has the power to ensure that the variable's host class gets evaluated before the variable is accessed:
class my_module::another_class {
include my_module::my_class
$the_date = $my_module::my_class::current_date
}

Is the `def` keyword optional? If so, why use it?

I am aware that a variable can be dynamically typed with the def keyword in Groovy. But I have also noticed that in some circumstances it can be left out, such as when defining method parameters, eg func(p1, p2) instead of func(def p1, def p2). The latter form is discouraged.
I have noticed that this is extendable to all code - anytime you want to define a variable and set its value, eg var = 2 the def keyword can be safely left out. It only appears to be required if not instantiating the variable on creation, ie. def var1 so that it can be instantiated as a NullObject.
Is this the only time def is useful? Can it be safely left out in all other declarations, for example, of classes and methods?
Short answer: you can't. There are some use cases where skipping the type declaration (or def keyword) works, but it is not a general rule. For instance, Groovy scripts allow you to use variables without specific type declaration, e.g.
x = 10
However, it works because groovy.lang.Script class implements getProperty and setProperty methods that get triggered when you access a missing property. In this case, such a variable is promoted to be a global binding, not a local variable. If you try to do the same on any other class that does not implement those methods, you will end up getting groovy.lang.MissingPropertyException.
Skipping types in a method declaration is supported, both in dynamically compiled and statically compiled Groovy. But is it useful? It depends. In most cases, it's much better to declare the type for a better readability and documentation purpose. I would not recommend doing it in the public API - the user of your API will see Object type, while you may expect some specific type. It shows that this may work if your intention is to receive any object, no matter what is its specific type. (E.g. a method like dump(obj) could work like that.)
And last but not least, there is a way to skip type declaration in any context. You can use a final keyword for that.
class Foo {
final id = 1
void bar(final name) {
final greet = "Hello, "
println greet + name + "!"
}
}
This way you can get a code that compiles with dynamic compilation, as well as with static compilation enabled. Of course, using final keyword prevents you from re-assigning the variable, but for the compiler, this is enough information to infer the proper type.
For more information, you can check a similar question that was asked on SO some time ago: Groovy: "def" keyword vs concrete type
in Groovy it plays an important role in Global and Local variable
if the variable name is same with and without def
def is considered local and without def its global
I have explained here in detail https://stackoverflow.com/a/45994227/2986279
So if someone use with and without it will make a difference and can change things.

Puppet passing parameters from profile to module

I have a module "base" with an init.pp class which has some parameters as such:
class base (
$listen_ip = "xx.xx.xx.xx",
$listen_port = 3306,
$admin_username = 'admin',
$admin_password = 'admin',
)
{
...
}
Then I have created a profile "base" where I want to set some of the parameters:
class profile::base {
class { 'base':
$listen_ip = "xxx.xxx.xx.xx",
$listen_port => 6033,
}
}
Then the is a secondary profile where I want to set the username and password:
class profile::department::sales::base {
class { '::profile::base':
$admin_username = "some_user",
$admin_password => "some_pw",
}
}
However it's not possible to set the parameters from the "sales" profile.
The idea is that some values will be always the same for the base class and that some differ based on the department.
However it's not possible to set the parameters from the "sales" profile.
Not exactly. What is not allowed is using two different resource-like declarations for the same class while building one manifest. If you use even one then you must make certain that it is the first (or only) declaration of that class that the catalog builder evaluates.
To understand this, you need to appreciate that assigning parameter values is not the principal purpose of declarations such you are using. The principal purpose is rather to specify that the class in question should be included in the catalog in the first place. In service to that goal, values are bound to all the parameters of a class at the point where its first declaration is evaluated. Thus, your two class declarations do not supplement each other. Instead, they conflict with each other.
Even if the parameter values it specified for class base were identical to those declared by class profile::base, however, Puppet would still object to all uses of class profile::department::sales::base. To simplify evaluation and be absolutely certain to avoid inconsistency, it implements a stronger constraint than is actually required: that only the first-evaluated declaration of any given class may be a resource-like one.
Note: the latest docs actually specify an even stronger constraint than that: "Resource-like class declarations require that you declare a given class only once." In practice, however, this is a simplification (in every version of Puppet so far released since the introduction of parameterized classes). It is likely inspired by the fact that the order in which Puppet manifests are evaluated can be difficult to predict, so if you use include-like declarations along with a resource-like declaration of the same class, in different manifests, then it can be hard to ensure that the resource-like one is always evaluated first.
The idea is that some values will be always the same for the base
class and that some differ based on the department.
For most purposes it is best to avoid resource-like class declarations altogether, relying instead on external data (Hiera) for binding values to class parameters. Hiera recognizes a hierarchy of data sources (hence the name) and supports specifying different parameters at different levels, and even overriding data from one level at a higher-priority level.
My suggestion, then, is to leverage Hiera to assign appropriate parameter values to class base. There are many ways the specifics could play out.

Can a GDScript class not extend anything?/Is there a class that every class must extend?

I'm making a GDScript class that shouldn't need to extend Node2D. It doesn't have an associated scene, and exists so that other classes in my project can interface with it, but will never be displayed directly by the engine. Can I simply not have the extends keyword at the top of the file?
You can extend Object or any of its descendants, not just Node.
I believe you can omit the extends statement and it will default to inheriting Reference, but you should be explicit and write extends Reference.
Read the docs on Object then Reference then Resource and see which one will work best for you.
You can then instance your new script like:
const MyScript = preload(‘path/to/my_script.gd’)
var my_script := MyScript.new()
Or if you have given your script a class_name you can omit the preload into constant step.

Saving Object State with Pickle (objects containing objects)

I'm trying to figure out how to serialize an object with Pickle to a save file. My example is an object called World and this object has a list (named objects) of potentially hundreds of instantiated objects of different class types.
The problem is that Pickle won't let me serialize the items within the World.objects list because they aren't instantiated as attributes of World.
When I attempt to serialize with:
with open('gsave.pkl', 'wb') as output:
pickle.dump(world.objects, output, pickle.DEFAULT_PROTOCOL)
I get the following error:
_pickle.PicklingError: Can't pickle <class 'world.LargeHealthPotion'>:
attribute lookup LargeHealthPotion on world failed
So, my question is: what is an alternative way of storing the world.objects list items so that they are attributes of world rather than list items that don't get saved?
UPDATE
I think my issue isn't where the objects are stored; but rather that the class LargeHealthPotion (and many others) are dynamically created within the World class by operations such as this:
def __constructor__(self, n, cl, d, c, h, l):
# initialize super of class type
super(self.__class__, self).__init__(name=n, classtype=cl, description=d, cost=c,
hp=h, level=l)
# create the object class dynamically, utilizing __constructor__ for __init__ method
item = type(item_name,
(eval("{}.{}".format(name,row[1].value)),),
{'__init__':__constructor__})
# add new object to the global _objects object to be used throughout the world
self._objects[item_name] = item(obj_name, obj_classtype, obj_description, obj_cost,
obj_hp, obj_level)
When this finishes, I will have a new object like <world.LargeHealthPotion object at 0x103690ac8>. I do this dynamically because I don't want to explicitly have to create hundreds of different types of classes for each different type of object in my world. Instead, I create the class dynamically while iterating over the item name (with it's stats) that I want to create.
This introduces a problem though, because when pickling, it can't find the static reference to the class in order to deconstruct, or reconstruct the object...so it fails.
What else can I do? (Besides creating literal class references for each, and every, type of object I'm going to instantiate into my world.)
Pickle does not pickle classes, it instead relies on references to classes which doesn't work if the class was dynamically generated. (this answer has appropriate exert and bolding from documentation)
So pickle assumes that if your object is from the class called world.LargeHealthPotion then it check that that name actually resolves to the class that it will be able to use when unpickling, if it doesn't then you won't be able to reinitialize the object since it doesn't know how to reference the class. There are a few ways of getting around this:
Define __reduce__ to reconstruct object
I'm not sure how to demo this method to you, I'd need much more information about your setup to suggest how to implement this but I can describe it:
First you'd make a function or classmethod that could recreate one object based on the arguments (probably take class name, instance variables etc.) Then define __reduce__ on the object base class that would return that function along with the arguments needed to pass to it when unpickling.
Put the dynamic classes in the global scope
This is the quick and dirty solution. Assuming the class names do not conflict with other things defined in the world module you could theoretically insert the classes into the global scope by doing globals()[item_name] = item_type, but I do not recommend this as long term solution since it is very bad practice.
Don't use dynamic classes
This is definitely the way to go in my opinion, instead of using the type constructor, just define your own class named something like ObjectType that:
Is not a subclass of type so the instances would be pickle-able.
When an instance is it called constructs a new game-object that has a reference to the object type.
So assuming you have a class called GameObject that takes cls=<ObjectType object> you could setup the ObjectType class something like this:
class ObjectType:
def __init__(self, name, description):
self.item_name = name
self.base_item_description = description
#other qualities common to all objects of this type
def __call__(self, cost, level, hp):
#other qualities that are specific to each item
return GameObject(cls=self, cost=cost, level=level, hp=hp)
Here I am using the __call__ magic method so it uses the same notation as classes cls(params) to create instances, the cls=self would indicate to the (abstracted) GameObject constructor that the class (type) of GameObject is based on the ObjectType instance self. It doesn't have to be a keyword argument, but I'm not sure how else to make a coherent example code without knowing more about your program.

Resources