Eiffel: Call use obsolete feature. Call to feature `to_string_8': Use `name_32' instead - eiffel

I have a warning I cannot get rid of neither understand:
Eiffel: Call use obsolete feature. Call to feature `to_string_8': Use 'name_32' instead
item_prototype is a DB_SERVICE where I redefine out
if attached {APP_CONFIGURATION}.application_instance.selected_entity_primary_key ({SIT_UTIL}.class_name_lowercase ({like item_prototype})) as l_pk then
One more point is that I wasn't able to copy the warning msg to my clipboard, how do I do that? if there is a way into EiffelStudio.

It looks like the feature {SIT_UTIL}.class_name_lowercase takes an argument of type STRING, but the current code supplies type TYPE [...] — the type of {like item_prototype}. There is a conversion feature to_string_8 in the class TYPE, but it is obsolete, that's why you get a warning.
Either the signature of the feature class_name_lowercase has to be changed to accept TYPE instead of STRING, or the argument should be of the form ({like item_prototype}).name_32.as_string_8.
In order to support Unicode identifiers, it's better to change the signature of class_name_lowercase anyway, so that it accepts STRING_32, and to pass ({like item_prototype}).name_32.

Related

Eiffel, multiple types conformance: a way to specify that a parameter is a descendent from A and B?

Is there a way (I'm sure there is out of runtime check...) to specify that a parameter or a variable in general conforms to multiple types? to avoid doing something such as
work (a_printer: PRINTER; a_scanner: SCANNER)
do
a_printer.print
a_scanner.scan
-- OR without second parameter
if attached {SCANNER} a_printer as l_scanner then
l_scanner.scan
else
throw RuntimeError
end
end
If feature work belongs to a class that may have formal generic parameters, it could be defined as taking one argument of the corresponding formal generic type:
class X [D -> {PRINTER, SCANNER}] feature
work (device: D)
do
device.scan
device.print
end
end
Then, at the caller site, one could make the call
x.work (multi_function_device)
where x has an appropriate type, e.g. X [MULTI_FUNCTION_PRINTER].
If work could also be declared and implemented as a class feature, the temporary variable could be avoided:
{X [like multi_function_device]}.work (multi_function_device)
If the auxiliary class X is not an option, the current version of the language provides no means to declare an argument as conforming to more than 1 type (e.g., work (d: {PRINTER, SCANNER})), so you would have to resort to preconditions like
work (p: PRINTER)
require
attached {SCANNER} p
do
check
from_precondition: attached {SCANNER} p as s
then
s.scan
end
p.print
end
I think that, if possible, you should use a common ancestor to your multiple types. If you cannot (if you are using library types), you can create descendant classes (MY_PRINTER inherit from PRINTER and DEVICE and MY_SCANNER inherit from SCANNER and DEVICE). Another way is to use ANY as the type, but it is not the best solution.

Only user-defined types defined in public modules can be coerced to or from a variant passed to late-bound functions

I have the following code, whereby I have declared an array or records as Member, the Member type consists of 3 entries, forename, surname and distance. I've tried many variations on my 'call' function but I keep getting the same error:
Here is a shortened format of my 'whole' code, hoping someone can point out whatever silly mistake I'm making here, I can only assume something within the parameter passing or declaration of the record structure?
Hope you can help with my school project.
Just like the message says. You're using a private type, and so it can't be coerced to Variant.
You probably want your Read_In_File Sub to instead declare the type of the parameter, rather than using the default Variant type.
Private Sub Read_In_File(ByRef Members As Member())
Though it's very odd to both have a global variable in your class and a parameter of the same name; so I'm not quite sure what exactly you're trying to accomplish.
The error message is telling you exactly how to solve your issue:
"Only user-defined types defined in public modules can be coerced to or from a variant passed to late-bound functions"
Add a Module to your project called MUserDefinedTypes or modUserDefinedTypes (or whatever naming convention you use) and declare your public user-defined type there.
I also agree with Peter in that you have some funny naming conventions in you code. Do not name your variables the same as you modules, classes, forms, or types. It will only get you into trouble. I suggest a simple prefix approach.

Why would it matter where a type declaration is located?

The documentation for ReasonReact specifies where in the code a type should be declared:
The state type could be anything! An int, a string, a ref or the common record type, which you should declare right before the reducerComponent call:
type state = {counter: int, showPopUp: bool};
let component = ReasonReact.reducerComponent "Dialog";
The emphasis is theirs.
Why would it matter where the type declaration is located, so long as it's valid? Does some kind of optimization take place only when the two lines are adjacent? What happens if I insert other things between them or put them in separate modules?
The type needs to be defined before it is used, but it doesn't matter in any technical sense whether there's anything in between. That's just convention, to keep related things together.
I'll see about getting this clarified in the docs.
Putting the state type (or the retainedProps type or the action type) after the component definition will give you a type error; if you turn on super-errors (like so: https://github.com/reasonml-community/bs-glob/blob/d891ce1fadd3f3b2938d5900eb15241be4a3c1d0/bsconfig.json#L3) then the error briefly explains itself.
In short, it's a corner-case typing issue (scope escape), whose explanations you can find elsewhere.

DirectCast (or alternative) with a value from Array Of Type as second argument?

I am writing a Class to error report explicitly to users who sent copied & pasted data via ajax.
I am trying to properly cast Types for INSERTion into sql server.
The user's data is stored in an Object(,). The Types are passed via ByVal ColumnTypes() As Type and stored inline:
{
GetType(Integer), GetType(String), GetType(Integer)
}
for example.
How can a value from the Array Of Type be used as the second argument of DirectCast (or an alternative to DirectCast)?
psuedo
DirectCast(thisVariable, ColumnTypes(0))
for an Integer
Unfortunately there is no way to achieve this. The DirectCast expression can only work with named types. Essentially values that are resolvable at compile time. The expression ColumnTypes(0) is only resolvable at runtime and hence can't be used with DirectCast in this manner.
Instead of DirectCast try using TypeConverter
TypeConverter.ConvertTo(thisVariable, ColumnTypes(0))

TCL/C - when is setFromAnyProc() called

I am creating a new TCL_ObjType and so I need to define the 4 functions, setFromAnyProc, updateStringProc, dupIntRepProc and freeIntRepProc. When it comes to test my code, I see something interesting/mystery.
In my testing code, when I do the following:
Tcl_GetString(p_New_Tcl_obj);
updateStringProc() for the new TCL object is called, I can see it in gdb, this is expected.
The weird thing is when I do the following testing code:
Tcl_SetStringObj(p_New_Tcl_obj, p_str, strlen(p_str));
I expect setFromAnyProc() is called, but it is not!
I am confused. Why it is not called?
The setFromAnyProc is not nearly as useful as you might think. It's role is to convert a value[*] from something with a populated bytes field into something with a populated bytes field and a valid internalRep and typePtr. It's called when something wants a generic conversion to a particular format, and is in particular the core of the Tcl_ConvertToType function. You probably won't have used that; Tcl itself certainly doesn't!
This is because it turns out that the point when you want to do the conversion is in a type-specific accessor or manipulator function (examples from Tcl's API include Tcl_GetIntFromObj and Tcl_ListObjAppendElement, which are respectively an accessor for the int type[**] and a manipulator for the list type). At that point, you're in code that has to know the full details of the internals of that specific type, so using a generic conversion is not really all that useful: you can do the conversion directly if necessary (or factor that out to a conversion function).
Tcl_SetStringObj works by throwing away the internal representation of your object (with the freeIntRepProc callback), disposing of the old bytes string representation (through Tcl_InvalidateStringRep, or rather its internal analog) and then installing the new bytes you've supplied.
I find that I can leave the setFromAnyProc field of a Tcl_ObjType set to NULL with no problems.
[*] The Tcl_Obj type is mis-named for historic reasons. It's a value. Tcl_Value was taken for something else that's now obsolete and virtually unused.
[**] Integers are actually represented by a cluster of internal types, depending on the number of bits required. You don't need to know the details if you're just using them, as the accessor functions completely hide the complexity.

Resources