NAME
VCS::CMSynergy::Object - convenience wrapper to treat objectnames as an object
SYNOPSIS
use VCS::CMSynergy;
$ccm = VCS::CMSynergy->new(%attr);
...
$obj = $ccm->object($name, $version, $cvtype, $instance);
$obj = $ccm->object($objectname);
print ref $obj; # "VCS::CMSynergy::Object"
# objectname and its constituents
print "...and the object is $obj";
print "name = ", $obj->name;
print "version = ", $obj->version;
print "cvtype = ", $obj->cvtype;
print "instance = ", $obj->instance;
print "objectname = ", $obj->objectname;
# attribute methods, optionally caching with
# use VCS::CMSynergy ':cached_attributes'
print $obj->get_attribute('comment');
$obj->set_attribute(comment => "blurfl");
$obj->create_attribute("foo", string => "some text");
$obj->delete_attribute("foo");
$hashref = $obj->list_attributes; # always caches result
# property methods
print $obj->property("bar");
print $obj->displayname; # always caches result
## tiehash interface
use VCS::CMSynergy ':tied_objects';
$ccm = VCS::CMSynergy->new(%attr);
...
print $obj->{comment};
$obj->{comment} = "blurfl";
# same as:
# print $ccm->get_attribute(comment => $obj);
# $ccm->set_attribute(comment => $obj, "blurfl");
This synopsis only lists the major methods.
DESCRIPTION
A VCS::CMSynergy::Object
is mostly a glorified wrapper for a Synergy's objectname (sometimes called object reference form in Synergy documentation). Because of its overloaded string conversion method (see below), it can be used with VCS::CMSynergy
methods wherever an objectname would be appropriate, esp. where the documentation specifies a file_spec.
When ":cached_attributes" in VCS::CMSynergy is in effect, a VCS::CMSynergy::Object
keeps a "demand loaded" cache of attribute names and values.
There is also a "TIEHASH INTERFACE" for manipulating an object's attributes using the hash notation.
BASIC METHODS
new
# let $ccm be a VCS::CMSynergy
$obj = VCS::CMSynergy::Object->new($ccm, $objectname);
# more conveniently
$obj = $ccm->object($name, $version, $cvtype, $instance);
$obj2 = $ccm->object("name~version:cvtype:instance");
Create a VCS::CMSynergy::Object
from a Synergy session and an objectname (sometimes called object reference form in Synergy documentation). You may use either the database delimiter or a colon to separate the name and version parts of the objectname.
Usually you would not call this method directly, but rather via the wrapper "object" in VCS::CMSynergy.
Note that no check is made whether the corresponding object really exists in the Synergy database, use "exists" for that.
Invoking new
several times with the same objectname always returns the same VCS::CMSynergy::Object
. This also holds for any method that returns VCS::CMSynergy::Object
s (by calling new
implicitly), e.g. "object" in VCS::CMSynergy or "query_object" in VCS::CMSynergy.
objectname
print $obj->objectname;
Returns the object's complete name in object reference form, i.e. "name:version:cvtype:instance"
. Note that the delimiter between name and version is canonicalized to a colon, i.e. independent of the value of database delimiter.
name, version, cvtype, instance
print $obj->name;
print $obj->version;
print $obj->cvtype;
print $obj->instance;
Returns the object's name, version, type, or instance, resp.
string conversion
VCS::CMSynergy::Object
overloads string conversion with "objectname", i.e. the following expressions evaluate to the same string:
"$obj"
$obj->objectname
This makes it possible to use a VCS::CMSynergy::Object
throughout VCS::CMSynergy
wherever an objectname would have been appropriate.
is_project, is_dir
if ($obj->is_project) { ... }
These are convenience functions that test whether the object's type is "project"
or "dir"
, resp.
ccm
$obj->ccm->query_hashref(...);
ccm
returns the session (a VCS::CMSynergy
) that is associated with the object.
cat_object
$contents = $obj->cat_object();
$obj->cat_object($destination);
A convenience wrapper for "cat_object" in VCS::CMSynergy.
mydata
Sometimes it is handy to be able to store some arbitrary data into a VCS::CMSynergy::Object
. This method returns a reference to a hash associated with the object. It is totally opaque w.r.t. Synergy operations.
ATTRIBUTE METHODS
get_attribute, set_attribute
$value = $obj->get_attribute($attribute_name);
$obj->set_attribute($attribute_name, $value);
These are convenience wrappers for "get_attribute" in VCS::CMSynergy and "set_attribute" in VCS::CMSynergy, resp., i.e.
print $obj->get_attribute("comment");
is syntactic sugar for
print $ccm->get_attribute("comment", $obj);
If you are use
ing ":cached_attributes" in VCS::CMSynergy, these methods maintain a cache of attribute names and values in the object. Note that this cache is only consulted if you use VCS::CMSynergy::Object
methods (including the "TIEHASH INTERFACE") and will get inconsistent if you mix VCS::CMSynergy::Object
and VCS::CMSynergy
calls on the same object.
create_attribute, delete_attribute
$obj->create_attribute($attribute_name, $attribute_type, $value);
$obj->delete_attribute($attribute_name);
Convenience wrappers for "create_attribute" in VCS::CMSynergy and "delete_attribute" in VCS::CMSynergy, resp. Also update the cache when ":cached_attributes" in VCS::CMSynergy is in effect.
copy_attribute
$obj->copy_attribute($attribute_name, @to_file_specs);
Convenience wrapper for "copy_attribute" in VCS::CMSynergy. Also invalidate the cache entries for $attribute_name
for all VCS::CMSynergy::Object
s in @to_file_specs
when ":cached_attributes" in VCS::CMSynergy is in effect.
Note: The optional $flags
parameter of "copy_attribute" in VCS::CMSynergy is not supported, because it would mean traversing the target projects to update or invalidate attribute caches.
list_attributes
$hashref = $obj->list_attributes;
Convenience wrapper for "list_attributes" in VCS::CMSynergy.
Note that the returned hash is always cached in the object (and updated for successful "create_attribute" and "delete_attribute" calls).
exists
print "$obj doesn't exist" unless $obj->exists;
Tests whether the VCS::CMSynergy::Object
corresponds to an object in the Synergy database (without causing an exception if it doesn't).
PROPERTY METHODS
property
$value = $obj->property($keyword);
$hash = $obj->property(\@keywords);
Convenience wrapper for "property" in VCS::CMSynergy, equivalent to
$value = $ccm->property($keyword, $obj);
$hash = $ccm->property(\@keywords, $obj);
displayname, cvid
print $obj->displayname;
print $obj->cvid;
Short hand for $obj->property("displayname")
or $obj->property("cvid")
, resp. However, these two methods cache their return value in the VCS::CMSynergy::Object
(because it is immutable). If ":cached_attributes" in VCS::CMSynergy is in effect, the cache may be primed using "query_object" in VCS::CMSynergy or similar methods, e.g.
$result = $ccm->query_object("...", qw( ... displayname ... ));
is_RELATION_of, has_RELATION
$tasks = $obj->has_associated_cv;
These are convenience methods to quickly enumerate all objects that are somehow related to the invoking object:
$obj->is_RELATION_of
$obj->has_RELATION
returns exactly the same as
$obj->ccm->query_object("is_RELATION_of('$obj')")
$obj->ccm->query_object("has_RELATION('$obj')")
If you supply extra arguments then these are passed down to "query_object" in VCS::CMSynergy as additional keywords, e.g.
$obj->is_RELATION_of(@keywords)
returns exactly the same as
$obj->ccm->query_object("is_RELATION_of('$obj')", @keywords)
See the Synergy documentation for the built-in relations. Note that it's not considered an error to use a non-existing relation, the methods will simply return (a reference to) an empty list. This is consistent with the behavior of ccm query in this case.
TIEHASH INTERFACE
use VCS::CMSynergy ':tied_objects';
...
print $obj->{comment};
$obj->{comment} = "blurfl";
When use
ing ":tied_objects" in VCS::CMSynergy, you can use a VCS::CMSynergy::Object
in the same way you would use a hash reference. The available keys are the underlying Synergy object's attributes.
Note that contrary to the behavior of real hashes, keys don't spring into existence "on demand". Getting or setting the value of an attribute that does not exist for the underlying Synergy object will return undef
or throw an excpetion (depending on your sessions's setting of "RaiseError" in VCS::CMSynergy). However, testing for the existence of an attribute with exists
works as expected.
NOTE: When using ":tied_objects" in VCS::CMSynergy, it is strongly recommended to have Scalar::Util installed. See "Why is Scalar::Util recommended?" for an explanation.
FETCH, STORE
$value = $obj->{attribute_name};
$obj->{attribute_name} = $value;
These are wrappers for "get_attribute" and "set_attribute", resp. The operate on the same cache as these when using ":cached_attributes" in VCS::CMSynergy
EXISTS
Checks the return value from "list_attributes" for the existence of the key (attribute) given.
FIRSTKEY, NEXTKEY
foreach (@{ $obj->keys }) { ... }
foreach (@{ $obj->values }) { ... }
while (my ($attr, $val) = each %$obj) { ... }
These methods use "list_attributes" to obtain a list of attributes and then iterate over this list. Hence keys
, values
, and each
all work as expected.
Warning: Enumerating the keys (i.e. attribute names) of a tied VCS::CMSynergy::Object
is cheap (at most one call to ccm attribute -la), but enumerating the values may result in lots of calls to ccm attribute -show. Tools like Data::Dumper or similar will implicitly enumerate all keys and values when invoked on a tied object. This is especially annoying when using the graphical Perl debugger Devel::ptkdb and mousing over a variable holding a tied object, because the debugger uses Data::Dumper to construct a printable representation of the object.
Why is Scalar::Util recommended?
Every VCS::CMSynergy::Object
keeps a reference to the session (a VCS::CMSynergy
) where it was created in. It needs this "back pointer" so it can implement methods that invoke Synergy operations, e.g. "get_attribute". These references can prevent the timely garbage collection of a session (esp. ccm stop called from "DESTROY" in VCS::CMSynergy) if a VCS::CMSynergy::Object
has a longer lifetime than its session. (The latter is actually a programmer error, but there's no way to enforce the correct lifetime rule.) To work around this we need to make the session reference not count w.r.t. to garbage collection. We use "weaken" in Scalar::Util for that. If the VCS::CMSynergy
object goes away before the VCS::CMSynergy::Object
gets destroyed, its session reference will become undef
. Any method called on the VCS::CMSynergy::Object
after this point that tries to invoke a session method will result in a (rightly deserved) error (Can't call method "..." on an undefined value
).