TLM get and peek

Hi UVM forum,
I am trying to understand the difference between TLM get and peek.
the UVM_class_reference writes “The get interfaces are used to retrieve transactions from other components. The peek
interfaces are used for the same purpose, except the retrieved transaction is not consumed”
I am trying to write a code that demonstrates this.

class A extends uvm_component;
   `uvm_component_utils(A)
    uvm_blocking_get_imp #(pkt,A) get_imp;
    pkt t;
    event pkt_e;
    function new(...)
    task run_phase(...)
       t=...create...;
       void'(t.randomize());
       t.print();
       #10;
       -> pkt_e;
       #10;
       t.print();
    endtask

   task get(output pkt t)
      @pkt_e;
      t=this.t;
   endtask
endclass : A

class B extends uvm_component;
   ...
   uvm_blocking_get_port #(pkt) get_port;
   pkt t;
   ...
   task run_phase(...)
      get_port.get(t);
endclass : B

I was expected that the second t.print() in class A would fail because B already consumed the transaction.
but in the simulator I do see t printed again.
I guess I don’t understand the “is not consumed” part
Please explain

In reply to shimonc:

Since you are implementing get(), it is totally up to you to define what it means to have a transaction ready to consume, and then consume it. Typically one thinks of a FIFO or queue where get() waits for something to appear in the queue, and then pops it off.

In reply to shimonc:

There are two principles at play here.

The consumption you mentioned refers to a FIFO behavior of throwing away object handles once a consumer “gets” it. You don’t have a FIFO implemented. This applicable to the consumer more than the producer. If you are trying to demonstrate this point, Id put the prints in the B class, have it call get a few times (which will block), and have class A put a few random transactions into a new fifo, which gets accessed by the get() task.

As far as the print, as soon as you create() the t object, the print will never fail. You have created a class handle which has memory allocated.

I thought that UVM does something different in the background regards get and peek.
like actually delete the class property.
But now I understand that it is semantic and the implementation is up to me.
Thanks .