[Xotcl] nx parameters
Gustaf Neumann
neumann at wu-wien.ac.at
Thu Dec 16 11:31:35 CET 2010
Dear Victor,
here is a scripted writeup to address your questions.
-gustaf neumann
===========================================================
package req nx::test
nx::Object create o
# The method setter registers an accessor method for instance
# variables. It provides "set" and "get" operations and value
# checking.
# Register accessor named x
o setter x
# Use the accessor method x as setter
# (set instance variable x to 1; returns 1)
? {o x 1} 1
# Use the accessor method x as getter
# (get the value of the instance variable x; returns 1)
? {o x 1} 1
# Define a setter with a value constraint
o setter x:int
? {o x 3} 3
? {o x a} {expected integer but got "a" for parameter "x"}
# The accessor function can be realized with some more
typing as well
# via the following method. So, the method "setter" does not
provide
# any additional functionality in terms of expressability of the
# language.
o public method y {value:int,optional} {
if {[info exists value]} {
return [set :y $value]
} else {
return [set :y]
}
}
? {o y 3} 3
? {o y a} {expected integer but got "a" for parameter "value"}
# Why are accessor function at all provided since instance
variables
# can be accessed as well without these? In nx it is easy
for an
# object to access the own instance variables via variable
resolvers
# (variable names starting with a single colon), butmore work to
# access the variables of other objects. One can use e.g.
the method
# "eval" to execute a script in the context of an object
(and to be
# able to use the variable resolver).
? {o eval {set :x 2}} 2
# So, an accessor method makes the access of public
variables easy, it
# provides the value constraints, one can use interceptors for
# tracing, refinement, etc.
# Ok, why do we need attributes?
# Attributes (as defined by nx) provide all functionalities
provided
# by the setter methods plus
# - some attribute life-cycle management (e.g. default
values), and
# - arbitrary meta-data
# For example, we can define an integer attributed named "z"
with a
# default value.
o attribute {z:int 123}
# return the default value
? {o z} 123
? {o z a} {expected integer but got "a" for parameter "z"}
# The example above is an object specifc attribute. In most
# situations, attributes are defined on the class level.
Attributes
# are inherited to subclasses (setters certainly as well).
nx::Class create Employee {
:attribute serial_number:int,required
}
nx::Class create Manager -superclass Employee {
# Project names are upper case, provided as an list,
which might be
# empty and are per default initialized to the empty list.
:attribute {projects:upper,0..n {}}
}
Manager create joe -serial_number 4711
# What about the meta-data? I want to use e.g. very special
meta-data,
# such as e.g. time-stamps.
# The method "attribute" creates so-called slot objects,
which are in
# turn nx objects. These slot objects can be initialized
like all
# other nx objects in a scripted way.
nx::Class create C {
# Create attributes "x" and "y" and script the
initialization of
# these attributes.
:attribute x {
set :timestamp [clock clicks]
}
:attribute y {
set :timestamp [clock clicks]
}
:create c1
}
# Print for every slot object the value of the timestamp, if it
# exists.
proc print_slots_and_timestamps {obj} {
foreach slot [$obj info lookup slots] {
if {[$slot eval {info exists :timestamp}]} {
puts "$slot created at [$slot eval {set :timestamp}]"
}
}
}
print_slots_and_timestamps c1
#
# Ok. What if I want to use a time-stamp for every attribute
of my
# application without having to write this for every occurance?
#
# Well, use the force, luke. Remember, we have quite a powerful
# underlying framework, supporting e.g. mixin, dynamic call
# definitions, etc.
::nx::Attribute mixin [Class new {
:method init {} {
set :timestamp [clock clicks]
next
}
}]
nx::Class create D {
# Create attributes "x" and "y" and script the
initialization of
# these attributes.
:attribute x
:attribute y
:create d1
}
print_slots_and_timestamps d1
#
# What if i want to use different kinds of attributes, such as
# e.g. persistent attributes and non-persistent attributes,
etc.? How
# can i define my on slotclasses if i need?
#
# Per default, attributes are of the class ::nx::Attribute.
One can
# certainly define subclasses of this class and specify
these classes
# during attribute creation. Since "attribute" is technically a
# method, the syntax is slightly different to the usual object
# creation.
#
# We define now "MyAttribute" as a subclass of
::nx::Attribute with an
# additional attribute named timestamp. The timestamp has
the actual
# timestamp as default.
#
::nx::MetaSlot create MyAttribute -superclass ::nx::Attribute {
:attribute {timestamp "[clock clicks]"}
}
# Use this type of attribute:
nx::Class create E {
:attribute x -slotclass MyAttribute
:attribute y -slotclass MyAttribute
:create e1
}
print_slots_and_timestamps e1
# A final question: i see that "attribute" is more powerful then
# "setter". Do I need as an enduser the method "setter" at all?
#
# No. I think, we could safely remove it from the default
method set
# for the final release.
#
# One other observation during this writeup: maybe
"slotclass" is to
# crude, we could use "class" or "type" instead (at some earlier
# state, we could not use technically "class"). We will
overthink
# this.
More information about the Xotcl
mailing list