Class: Universa::Ref

Inherits:
Object
  • Object
show all
Defined in:
lib/universa/umi.rb

Overview

A reference to any Java-object that can call its methods like usual methods:

key = umi.instantiate "PrivateKey", 2048 # this returns Ref
address = key.getPublicKey().getShortAddress().toString()

Notice that all methods called after key are java methods of PrivateKey, PublicKey and KeyAddress Java classes, whose references are created on-the-fly automatically (and will be reclaimed by GC on both ends soon).

Instances are uniqie

What means, if some calls will return the same Java object instance, it will be returned as the same Ref instance.

Reference equality (== and !=)

References are equal if they refer the same objects OR their are equals - the java.equals() is called to compare different referenced objects. Therefore, to compare two references use:

  • ‘==`: returns true if referencs are to the same object or different objects that where left.equals(right)

    returns true.
    
  • ‘!=`: same as !(left == right)

  • ‘===`: thest that references refer to exactly same object instance. E.g. it is possible that

    `left == right && !()left === right) - different objects which `equals()`.
    

Reference lifespan

Each Ref has an allocated object in the remote side which is retained until explicetly freed by the proper UMI call. Ref class rakes care of it: when the ruby Ref instance is garbage collected, its remote counterpart will shortly receive drop command preventing memory leakage.

Arguments

you can use basic ruby objects as arguments: strings, numbers, arrays, hashes, and Ref instances too. Note that:

  • binary string (Encoding::Binary) are converted to byte[] iin Java side

  • utf8 strings are passed as strings.

Return value

Will be deep-converted to corresponding ruby objects: hashes, arrays, sets, numbers, strings and Ref instances as need. It is, generally, inverse of converting arguments covered above.

Instance Method Summary collapse

Constructor Details

#initialize(umi, ref) ⇒ Ref

Create new reference. Do not call it directly: the UMI instance will do it in a correct order.

Parameters:

  • umi (UMI)

    instance to bind to

  • ref (Hash)

    UMI reference structure



414
415
416
417
# File 'lib/universa/umi.rb', line 414

def initialize(umi, ref)
  @umi, @ref = umi, ref
  @id = ref.id
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

Internal use only. Call remote method as needed. This is where all the magick comes from: it call remote method instead of the local one, exactly like it is local.



441
442
443
444
445
446
447
# File 'lib/universa/umi.rb', line 441

def method_missing(method_name, *args, &block)
  if method_name[0] == '_'
    super
  else
    @umi.invoke self, method_name, *args
  end
end

Instance Method Details

#==(other) ⇒ Object

Checks that references are euqal: either both point to the same remote object or respective remote objects are reported equals by the remote equals() call.



462
463
464
465
# File 'lib/universa/umi.rb', line 462

def ==(other)
  (other.is_a?(Ref) || other.is_a?(RemoteAdapter)) && other._umi == @umi &&
      (other._remote_id == @id || other.equals(self))
end

#===(other) ⇒ Object

Equal references. Both point to the same remote object. Note that it should never happen with UMI class as it do cache non-recycled references and share them between calls.



469
470
471
# File 'lib/universa/umi.rb', line 469

def ===(other)
  other.is_a?(Ref) && other._umi == @umi && other._remote_id == @id
end

#_as_umi_arg(umi) ⇒ Object

Internal use only. This allow Ref instance to be an argument to the remote call. Convert it to proper UMI structure.



450
451
452
453
# File 'lib/universa/umi.rb', line 450

def _as_umi_arg(umi)
  umi == @umi or raise InterchangeError
  @ref
end

#_remote_class_nameObject

name of the remote class (provided by remote)



430
431
432
# File 'lib/universa/umi.rb', line 430

def _remote_class_name
  @ref.className
end

#_remote_idObject

Returns remote object id. Could be of any type actually.

Returns:

  • (Object)

    remote object id. Could be of any type actually.



425
426
427
# File 'lib/universa/umi.rb', line 425

def _remote_id
  @id
end

#_umiUMI

Returns interface that this reference is bound to (and created by).

Returns:

  • (UMI)

    interface that this reference is bound to (and created by)



420
421
422
# File 'lib/universa/umi.rb', line 420

def _umi
  @umi
end

#inspectObject

short data label for instance



456
457
458
# File 'lib/universa/umi.rb', line 456

def inspect
  "<UMI:Ref:#{@umi.__id__}:#{@ref.className}:#{@id}>"
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Internal use only. Allow processing remote commands as local calls

Returns:

  • (Boolean)


435
436
437
# File 'lib/universa/umi.rb', line 435

def respond_to_missing?(method_name, include_private = false)
  method_name[0] == '_' || LOCAL_METHODS.include?(method_name) ? super : true
end