Can enum be extended in upgradeable contract? - solidity

Can enum be extended in upgradeable contract, adding new value into the enum? If it can be extended, what are the consideration I should do before extending the enum?

Enums are internally just integers that start counting from 1.
As long as you are adding numbers that do not conflict with the original enum value set, the low level EVM does not care (though Solidity compiler might).

Related

What is the purpose or possible usages of value class in Kotlin

I found the new value class been
I found the purpose is like :
value class adds attribute to a variable and constraint it’s usage.
I was wondering what is some practical usage of value class.
Well, as stated in the documentation Kotlin Inline classes
Sometimes it is necessary for business logic to create a wrapper around some type. However, it introduces runtime overhead due to additional heap allocations. Moreover, if the wrapped type is primitive, the performance hit is terrible, because primitive types are usually heavily optimized by the runtime, while their wrappers don't get any special treatment.
To solve such issues, Kotlin introduces a special kind of class called an inline class. Inline classes are a subset of value-based classes. They don't have an identity and can only hold values.
A value class can be helpful when, for example, you want to be clear about what unit a certain value uses: does a function expect me to pass my value in meters per second or kilometers per hour? What about miles per hour? You could add documentation on what unit the function expects, but that still would be error-prone. Value classes force developers to use the correct units.
You can also use value classes to provide clear means for other devs on your project on doing operations with your data, for example converting from one unit to another.
Value classes also are not assignment-compatible, so they are treated like actual new class declarations: When a function expects a value class of an integer, you still have to pass an instance of your value class - an integer won't work. With type aliases, you could still accidentally use the underlying type, and thus introduce expensive errors.
In other words, if you simply want things to be easier to read, you can just use type aliases. If you need things to be strict and safe in some way, you probably want to use value classes instead.

In Kotlin, what's the difference between start and first?

I'm learning Kotlin, but I can't seem to find straight answers to simple questions. I presume that it's so new, no one has had a chance to ask the obvious questions yet. So here it goes.
When I want to get the smallest item in a range, I type:
range.start
But I get the warning, "Could be replaced with unboxed first". Not sure what unboxed means--can't even guess. But when I use this command:
range.first
the warning goes away. What's happening here? Should I even be concerned? Why does Kotlin have both a start and a first?
Boxing and unboxing refers to wrapping a primitive value in a class so it can be used with generic classes and functions or as a nullable. In Java, this is more transparent because the primitive and boxed versions of each type of variable have different names (i.e. int and Integer), whereas in Kotlin this is not very obvious. If your variable is nullable, like Int?, it is always boxed, but if it's non-nullable, it's only boxed if it's passed to a function that's generic or requests a nullable version. So boxing as a verb refers to the variable getting wrapped in a class at the moment it is passed to something that requires a boxed version.
There is an interface for a generic range called ClosedRange. When you are working with integer ranges, you are using a class called IntRange that also implements ClosedRange<Int>.
When you use the properties of the generic interface like start, the JVM has to box and unbox your Int value. This is because generics cannot be used with non-boxed primitives. There is a small amount of runtime overhead to box and unbox the primitive.
The actual class IntRange stores the values for the start and end of the range as primitives, so if you access them directly with first, you bypass the boxing that occurs if you go through the generic interface property, for a small performance gain.
In the vast majority of cases, the performance difference will be negligible anyway, but the default code inspection recommends you to use the more performant way.

Type pool or class of constants?

What is the difference between Type-pool and creating a class for constants?
What is better?
My question is for a large group of constants and to be accessible to other groups.
Thank you
EDIT - Thank you for the answers and I will improve my question. I need something to store constants and I will use them on programs or other classes. Basically, I wanted to know if it is better to use a type-pool or a class with constants (only). I can have more than one class or type-pool.
The documentation mentions this:
Since it is possible to also define data types and constants in the public visibility section of global classes, type groups are obsolete and should no longer be created. Existing type groups can still be used.
A sensibly named interface with the constants you desire is the way to go. An additional benefit is that ABAP OO enforces some more rules.
Agree with #petul's answer, except for one detail: I'd recommend creating one enumeration-like class per logical group of constants, instead of collecting constants in interfaces.
Consider using the new enum language feature for specifying the constant values.
Interfaces can be accidentally "implemented", which doesn't make sense here. Classes can prevent this with final.
Making one class per logical group simplifies finding the constants with IDE features such as Ctrl+Shift+A search in the ABAP Development Tools. Constants that are randomly thrown together into interfaces are hard to find later on.
Classes allow adding enumeration-like helper methods like converters, existence checks, numbering all values.
Classes also allow adding unit tests, such as ensuring that the constant collection is still in sync with the fixed values of an underlying domain.

Decoupling a class which is used by the lots of subclasses

Hi I have a situation like that;
I have different items in my design and all these items has some specific effect on the Character. There is an apply function in every item so it can use Character object and change its functionalities. But what if I change the Character function, I would have to change all the Item classes in accordance to that.
How can I decouple Item and Character efficiently?
The language I am going to use is C++ and I don't know the other variables and functions inside the Item and Character classes. I just want to decouple them.
You could introduce an interface (abstract class in C++) that Character would inherit. Let's call it ItemUser. The Item#apply signature would be changed so that it would take an object of ItemUser instead of Character. Now you are able to change the implementation of Character freely as long as it respects the ItemUser contract.
Check Decorator design pattern, it seems that this design pattern is what you are looking for. Link :Decorator design pattern
As per what I have understood from reading your question is : You have multiple Item classes each having a effect associated. Effect corressponding to the type of Item object is applied on another entity which is Character. Now your issue is whenever there is a change in Character class your Item classes also needs to change and you want a cleaner way to avoid this.
A good way to handle change is to define the well defined Contract which is less prone to change. For example if we have a functionality to add two integers and later we may have the changes such that we require to add two floating point numbers and later we may need to replace add operation with multiplication. In such a case you can define an abstraction Compute (INum num1, INum num2) : INum as return type. Here INum is an abstraction for type and Compute is abstraction for behaviour of function. Actual implementation defines INum and Compute. Now code using our code only depends on the abstractions and we can freely modify the operation and actual type without affecting the user code.
While implementing the contract you can modify the internal implementation without affecting the outside code using the contract.
You can define an abstract class ICharacter. For certain attributes whose type can change in future you can use Templates and generics or simply create interface for the attribute type as well and let the concrete type implement the interfaces. Refer all your fields with interfaces. Let ICharacter define public abstract methods with parameters of type Interfaces and return type also as Interfaces.
Let Item class use ICharacter and When you need to apply effect as per item class just use the constant abstract functions defined. Your Character internal modifications now can change without affecting the Item class.

Can we use tracking handle to the value class?

Using c++ CLI, is it recommended not to use tracking handle for value class?
for example
value class Point {
};
Point p;
or Point ^p;
C++/CLI permits that syntax, unfortunately, it cannot be expressed directly in other managed languages. You end up with the value getting boxed in an object and stored on the GC heap. Every assignment will box, reading the value unboxes it again. That's quite expensive and 99.9% of the time is the wrong thing to do. The point of value types is to make your code fast, avoiding the extra indirection through an object reference and taking advantage of processor registers. A value type value like Point fits in two registers.
By declaring it as a handle, you get the disadvantage of a ref class but add the expense of having to unbox the value every time you retrieve a member of the value type. It therefore makes no sense to do this at all, if you need a Point class with reference type semantics then just declare a ref class Point and entirely avoid the un/boxing cost. C++/CLI has a few design flaws, induced by trying make it match native C++ semantics. This is one of them.
So no, this is not recommended.