Implementation contraint: The class feature only_from_type uses an inline agent - eiffel

Is there a semantic behind not being able to have an agent into a ensure class routine or is it a current compiler restriction?
only_from_type (some_items: CHAIN[like Current]; a_type: detachable like {ENUMERATE}.measuring_point_type_generation): LINKED_LIST[like Current]
-- extends Result with given some_items which are equal to given type
do
create Result.make
across
some_items is l_item
loop
check
attached_type: attached l_item.type as l_type
then
if attached a_type as l_a_type and then l_type.is_equal (l_a_type) then
Result.extend (l_item)
end
end
end
ensure
some_items.for_all (
agent (an_item: like Current; a_type_2: detachable like {ENUMERATE}.measuring_point_type_generation) do
if attached a_type_2 as l_type_2_a and then
attached an_item.type as l_item_type and then
l_item_type.is_equal (l_type_2_a)
then
Result := True
end
end (a_type)
)
instance_free: Class
end
gives following error
And I think there is a typo here, shouldn't it be Implementation constraint instead of contraint?
Error code: VUCR
Implementation contraint: The class feature only_from_type uses an inline agent.
What to do: Remove the inline agent from the code or make the feature a non-class one.
Class: MEASURING_POINT
Feature: only_from_type
Line: 183
some_items.for_all (
-> agent (an_item: like Current; a_type_2: detachable like {ENUMERATE}.measuring_point_type_generation) do
if attached a_type_2 as l_type_2_a and then

An inline agent (like a regular feature) takes an implicit argument - current object. In a class feature (where it is used in the example), there is no current object. Therefore, an inline agent cannot be called from a class feature.
On the other hand, it might be possible to check that the agent does not use Current, and, therefore, is safe to use in the class feature. The compiler reporting the error does not implement such a functionality, and reports an implementation constraint error instead.

Related

Compile error when trying to use jooq any operator in kotlin

I have problems using jooq with kotlin and the any clause.
Given the following:
I have a Database field in a postgreSQL database which is an array
I have search parameters which are a List of Strings
I want to use jooq any operator to search in the array
I have the following code which is not working:
fun findAll(
someArrayListOfStrings: List<String>?
): List<SomeDTO> {
val filters = ArrayList<Condition>()
filters.add(TABLE.SOME_FIELD.eq(DSL.any(someArrayListOfStrings)))
}
Here I want to dynamically create filters (jooq Conditions) to be added to some SQL statement. It should work to look if SOME_FIELD (PostgreSQL Array Type) contains one of the following strings using the ANY clause (PostgreSQL jooq binding). However I get the following compile-time error:
None of the following functions can be called with the arguments supplied:
public abstract fun eq(p0: Array<(out) String!>!): Condition defined in org.jooq.TableField
public abstract fun eq(p0: Field<Array<(out) String!>!>!): Condition defined in org.jooq.TableField
public abstract fun eq(p0: QuantifiedSelect<out Record1<Array<(out) String!>!>!>!): Condition defined in org.jooq.TableField
public abstract fun eq(p0: Select<out Record1<Array<(out) String!>!>!>!): Condition defined in org.jooq.TableField
But my function call should match the third type where QuantifiedSelect is used.
I looked for hours on the internet but was not able to find any solution. Any site I found told me to try the solution I already have. Does anyone have an idea what I could try and why it does not work?
Thank you!
The method you're calling here is DSL.any(T...), which takes a generic varargs array (in Java). You're passing a List<String>, so this binds T = List<String>, which doesn't satisfy the type constraint on the eq() method.
But even if you changed that to an Array<String>, it wouldn't work because the jOOQ ANY operator doesn't do the exact same thing as the PostgreSQL any(array) operator. So, just resort to either plain SQL templating:
condition("{0} = any({1})", TABLE.SOME_FIELD,
DSL.value(someArrayListOfStrings.toTypedArray()))
Or just use the IN predicate
TABLE.SOME_FIELD.in(someArrayListOfStrings)

Error code: VUTA(3) Error: separate target of the Object_call is not controlled

I'm a complete beginner to Eiffel and I'm implementing a linked list as an exercise. I get the following error in the feature has (which tells you if the list contains v).
Error code: VUTA(3)
Error: separate target of the Object_call is not controlled.
What to do: ensure the target of the call is controlled or is not separate.
Class: MY_LINKED_LIST [G]
Feature: has
Type: Generic #1
Line: 159
then
-> if l_cursor_a.item.is_equal (v) then
Result := True
The weird thing is that when I change the '.is_equal' for a '=' the error is gone. I don't know what 'controlled' in the error description means and what difference to it does make to use '=' in this context. The code is the following:
MY_LINKED_LIST[G]
class
MY_LINKED_LIST[G]
feature -- Access
item: G
require
not off
do
check
off: attached cursor as l_cursor
then
Result := l_cursor.item
end
end
first,
last: detachable like item
feature -- Measurement
count: INTEGER
feature -- Element change
feature -- Status report
index: INTEGER
before: BOOLEAN
after: BOOLEAN
has (v: like item): BOOLEAN
require
local
l_cursor: like cursor
do
from
l_cursor := first_element
until
not attached l_cursor or Result
loop
check
attached l_cursor as l_cursor_a
then
if l_cursor_a.item.is_equal (v) then
Result := True
end
l_cursor := l_cursor_a.next
end
end
ensure
function_not_change_state: item = old item
end
feature {NONE} -- Implementation
cursor,
first_element,
last_element: detachable MY_CELL[G]
end -- class
MY_CELL[G]
class
MY_CELL[G]
feature -- Access
item: G
The error message is related to SCOOP — the model of concurrent programming built into Eiffel. According to it, a feature can be called on a separate object only when the object is controlled. This is achieved when the target of the call is an argument of a feature, or when a special separate instruction is used. In your case, the latter would look like
separate l_cursor_a.item as x do
if x.is_equal (v) then
Result := True
end
end
Why l_cursor_a.item is considered separate in the first place? It has a type G, and the formal generic is unconstrained that is identical to have a constraint detachable separate ANY (so, most probably, the code above would not compile, you would need to make sure x is attached before calling is_equal on it).
The equality operator = does not perform any calls (unless the involved types are expanded, but expanded types are never separate). For reference types (including separate ones), it simply tests whether two references are the same. This explains why the error disappears when is_equal is replaced with =.
An alternative solution to avoid the error message is to change the constraint of the formal generic to be non-separate: MY_LINKED_LIST [G -> detachable ANY].
Side note. The check instruction check attached l_cursor as l_cursor_a then ... seems to be redundant, the compiler should be able to figure out automatically that l_cursor is attached.

How to call a function with void return using Firedac FDConnection Component in Delphi XE5?

I recently started using the [ExecSQLScalar]1 and [ExecSQL]2 methods of the FDConnection component in Delphi XE5. It's very handy not to need to build a Dataset object, like FDQuery just for simple queries or executions.
However I had a curious problem when executing a function with void return that has internal validations where it can generate exceptions. I'm using a Postgres database.
CREATE FUNCTION can_be_exception()
RETURNS void AS
$$
BEGIN
RAISE EXCEPTION E'fail';
END;
$$
LANGUAGE plpgsql STABLE;
In delphi, I call the ExecSQLScalar function ...
FDConnection1.ExecSQLScalar('select 1');
FDConnection1.ExecSQLScalar('select can_be_exception()');
On first run, I get the following error:
Project TFDConnectionDEMO.exe raised exception class
EPgNativeException with message '[FireDAC][Phys][PG][libpq] ERROR:
fail'.
On the second run, I get a Violation Access error:
Project TFDConnectionDEMO.exe raised exception class $C0000005 with
message 'access violation at 0x00000000: read of address 0x00000000'.
Apparently the error occurs in the line below in unit FireDAC.Comp.Client
function TFDCustomConnection.ExecSQLScalar(const ASQL: String;
const AParams: array of Variant; const ATypes: array of TFieldType): Variant;
var
oCmd: IFDPhysCommand;
begin
oCmd := BaseCreateSQL;
try
if BasePrepareSQL(oCmd, ASQL, AParams, ATypes) or (FExecSQLTab = nil) then begin
FDFree(FExecSQLTab);
...
ignoring the previous error and trying again, another error is displayed...
Project TZConnectionDEMO.exe raised exception class EFDException with
message '[FireDAC][DatS]-24. Row is not nested'.
Searching, I found no response to this error. I figured my mistake would be to call the bank raise_exception function using the ExecSQLScalar function of the FDConnection component. So I tried using FDConnection.ExecSQL and as I imagined, you can not use this if there is a SELECT clause in the parameter.
Is there a better way to call function with void return using FDConnection.ExecSQL? would a BUG be in the component? or would not it be correct to make that kind of call?
Using ExecSQLScalar is fine in this case. This is certainly a bug (which was already fixed, at least in Delphi 10.2.3). As you've correctly pointed out, the problem is in releasing a table storage object instance held by the FExecSQLTab field by using FDFree procedure.
I don't have Delphi XE5 source code but maybe you can see something like this inside (comments about what happened are added by me):
if BasePrepareSQL(oCmd, ASQL, AParams, ATypes) or (FExecSQLTab = nil) then
begin
FDFree(FExecSQLTab); { ← directly calls destructor if object is not nil }
FExecSQLTab := oCmd.Define; { ← no assignment if command execution raises exception }
end;
Problem was that when a SQL command execution raised exception during storage table definition stage (oCmd.Define), reference to previously destroyed storage table object instance (by FDFree) remained stored in the FExecSQLTab field (as a dangling pointer).
Then when a different command was executed that way, FDFree procedure was called just for that dangling pointer. Hence the access violation.
Way to correct this is replacing line e.g. by:
FDFree(FExecSQLTab);
by:
FDFreeAndNil(FExecSQLTab);
which was done in some later Delphi release.

Ada : operator is not directly visible

I'm using GNAT GPS studio IDE in order to train a bit in Ada. I'm having an issue with package visibility.
First I specify a package in a file called "DScale.ads" containing a type:
package DScale is
type DMajor is (D, E, F_Sharp, G, A, B, C_Sharp);
end DScale;
Then I specify in a different file ("Noteworthy.ads") a package that defines a procedure that will use the DMajor type of the DScale package:
with Ada.Text_IO;
with DScale;
package NoteWorthy is
procedure Note;
end NoteWorthy;
Finally in "Noteworthy.adb" I provide the package body for the package "Noteworthy":
with Ada.Text_IO; use Ada.Text_IO;
package body Noteworthy is
procedure Note is
package ScaleIO is new Enumeration_IO(DScale.DMajor);
thisNote : DScale.DMajor := DScale.D;
begin
ScaleIO.Get(thisNote);
if thisNote = DScale.DMajor'First then
Put_Line("First note of scale.");
end if;
end Note;
begin
null;
end NoteWorthy;
If I leave the code as-is, I will get an "operator not directly visible" error for the "if thisNote = DScale.DMajor'First then" statement in the body of the "Noteworthy" package.
Is there a way to bypass this error without using a "use" or "use type" clause?
Thank you.
There are (at least) two answers to your question.
1:
if DScale."=" (thisNote, DScale.DMajor'First) then
2:
function "=" (Left, Right : DScale.DMajor) return Boolean renames DScale.DMajor;
...
if thisNote = DScale.DMajor'First then
But why would you use one of those options instead of:
use type DScale.DMajor;
...
if thisNote = DScale.DMajor'First then
Ada types are much more than just descriptions of the values, they are entities that bring into existence a whole slew of operations, embodied as both operators and attributes. So if you want direct visibility to a type's concrete "=" operator, you have to make it visible. For that you need either "use" or "use type".
Why bypass a language feature? Simply use it wisely.
A couple of points that are related to the structure of your code.
The package spec for Noteworthy doesn't need to "with DScale" as there is nothing in the spec that refers to any feature in that package (maybe you plan to in the future).
The use of enumeration_io is good if you want to simply want to do I/O to files to be read by a computer, but I would never use it for human interaction (apart from quick hacks). The input values it accepts is dictated by Ada's grammar, and typically not what user's expect.

How to perform uvm_do_on without randomization?

I have a virtual sequencer from which I execute three transactions in parallel, each one on its corresponding sequencer. So I have something like this:
class top_vseqr extends uvm_seqr extends uvm_sequencer;
type_a_seqr seqr_a;
type_b_seqr seqr_b;
type_c_seqr seqr_c;
...
endclass: top_vseqr
class simple_vseq extends uvm_sequence;
`uvm_declare_p_sequencer(top_vseqr)
type_a_seq seq_a;
type_b_seq seq_b;
type_c_seq seq_c;
...
virtual task body();
fork
`uvm_do_on(seq_a, p_sequencer.seqr_a)
`uvm_do_on(seq_b, p_sequencer.seqr_b)
`uvm_do_on(seq_c, p_sequencer.seqr_c)
join
endtask: body
endclass: simple_vseq
But now I want to be able to drive specific transactions into the virtual sequencer, depending on the test I am running. To do so, I have a class with an analysis import that is updated every time the monitor sees a transaction in the interface, and a function that returns the next transaction to be driven. So now I want to do something like the following:
class test extends uvm_test;
model model_a;
simple_vseq seq;
top_vseqr virt_seqr;
...
task run_phase(uvm_phase phase);
...
seq = simple_vseq::type_id::create("seq", this);
seq.seq_a = model_a.get_sequence();
seq.start(virt_seqr);
...
endtask: run_phase
Digging through the UVM documentation I have seen that there is a 'uvm_send macro, but it doesn't allow you to select the sequencer to run the sequence on (i.e. I haven't seen a 'uvm_send_on or something like that). What can I do?
Thanks!
You can implement the contents of the uvm_do_on macro without the call to randomize() (like you showed in the second snippet) without any worries. This is anyway the suggested practice by some experts, because the sequencer/driver handshake mechanism is pretty simple. The `uvm_do* macros are not the norm, they're just there to help you out in the beginning.
I don't think there is a `uvm_send_on macro but there is a `uvm_create_on(SEQ_OR_ITEM, SEQR) macro which you can use. From the UVM documentation, this is the same as `uvm_create except that it also sets the parent sequence to the sequence in which the macro is invoked, and it sets the sequencer to the specified ~SEQR~ argument. In fact, the `uvm_create macro calls `uvm_create_on macro internally by passing m_sequencer by default. You can override it using the `uvm_create_on call.
Alternatively, you could also do a set_sequencer on your sequence_item object so that it sets the m_sequencer variable.
Hope this helps.
`uvm_do_on_with may statisfis your requirement, and you can also delete rand in your packet to disable randomization or add constraint

Resources