With complete void check set in compiler I've got a Variable is not properly set compilation error on following case which for me is right (in my mind). It says that the source of assignment is not compatible with target. What am I missing here??? (DB_SERVICE.load_from_primary_key...
)
deferred class
DB_SERVICE [G -> DB_ENTITY create make_from_db_result end]
inherit
ACTION
redefine
start,
execute
end
LOGGABLE
rename
make as make_from_loggable
end
feature -- Creation
make (a_db_connection: attached DB_CONNECTION)
require
valid_db_connection: a_db_connection.is_connected
do
make_from_loggable
db_connection := a_db_connection
create last_items.make (100)
create last_column_names.make_empty
ensure
db_connection_setted: a_db_connection = db_connection and db_connection.is_connected
end
feature -- Access
item: detachable G
db_connection: DB_CONNECTION
last_items: HASH_TABLE[like item, INTEGER] -- content of last resultset
last_column_names: ARRAY[STRING] -- Column names of last resultset
feature -- status_report
load_from_primary_key (primary_key: INTEGER)
-- Loads given item into item otherwise item will be Void
require
attached db_connection.base_selection
local
l_db_result: DB_RESULT
do
if attached db_connection.base_selection as bs then
bs.query ("SELECT * FROM " + ({attached like item}).out + " WHERE " + {attached like item}.Primary_key_db_column_name + "=" + primary_key.out)
if bs.is_ok then
bs.load_result
create item.make_from_db_result(last_column_names, bs.cursor)
else
item := Void --HERE is the compiler complaining!
logger.write_critical ("Error while retreiving " + ({like item}).out + " from DB")
end
else
item := Void
logger.write_error ("base_selection is void")
end
end
end -- class
class
COMPANY_SERVICE
inherit
DB_SERVICE[COMPANY]
redefine
make
end
...
class
COMPANY
inherit
DB_ENTITY
rename
primary_key as id,
set_primary_key as set_id,
Primary_key_db_column_name as Id_db_column_name
redefine
make,
make_from_db_result,
out
end
create
make,
make_from_db_result
....
The type declaration detachable G
indicates that if the corresponding actual generic is a reference type, the variable of that type could be detachable. In that case it would be OK to assign Void
to such a variable. However, it's also possible that the actual generic is an expanded type. Prefixing an expanded type with detachable
has no effect, the type remains the same and the variable cannot be assigned Void
.
As an example, let's consider a simpler case, when there is no formal generic constraint for the parameter G
. An actual generic could be STRING
, and the variable item
has a type detachable STRING
. In this case, it's OK to assign Void
to item
.
Now, if the actual generic is INTEGER
, the variable has a type detachable INTEGER
that is equivalent to INTEGER
. Assigning Void
to a variable of this type makes no sense and is not permitted by the language rules.
The variable item
still can be set to Void
if the actual generic parameter is a reference type. For that, a local variable with the same type can be declared and its value can be assigned to item
:
local
default_item: like item
do
item := default_item