Perl6 Object Oriented Cookbook (v0.2.1)  
Section 6: Context and Transformation  
 
Recipe 6.2: Constructing an Object from Different Sources
Last Updated: Sep 8, 2003
Status: Draft
      Previous Page   Next Page

How important is this problem to you?
  (Login to Vote)
4.50 Rating, 2 Votes  

How acceptable is the proposed solution?
  (Login to Vote)
4.00 Rating, 1 Vote  

Problem:  

You want to allow your class to be instantiated via a transformation of some other value or object.

Solution:  

Use from to define contextual constructors:

class MyClass {
    from integer      { ... };
    from string       { ... };
    from AnotherClass { ... };
}

$obj = MyClass.new;                    # the normal way
$foo = AnotherClass.new;

# these don't need the parens, but it might be clearer with them

$obj = (MyClass from 5);         # uses the 'integer' transformation
$obj = (5 as MyClass);           # symmetric

$obj = (MyClass from 'foo');     # uses the 'string' transformation
$obj = ('foo' as MyClass);       # symmetric

$obj = (MyClass from $foo);      # uses the 'AnotherClass' transformation
$obj = ($foo as MyClass);        # symmetric

Discussion:

The from keyword defines the contextual transformations allowed when attempting to instantiate an object. Each one acts as an "alternate" constructor method; which one is called depends on what class or value you're trying to coerce into an instance of your object. In other words, it's exactly like having many variations of a new method, each tailored to working with different data.

In the declaration form, shown above, from takes two arguments; the context or contexts being declared, and an anonymous constructor method that will translate the object in that context. You don't have to define every possible context: perl will look for the 'closest' match, and use that. Constructor methods defined using this form will be indistinguishable from multimethod variants of the new constructor; it's just another way to express it. Note that you can use from when you need to pass only one single value to the constructor; it can't be used for more complex constructors that require multiple arguments.

The operator form of from, shown in the example, allows you to force a particular context upon the object. It is almost symmetric with as, but with the following caveat:

It is possible -- and even common -- for a transformation from one type to another to be accomplished in a variety of ways. In general, perl looks for the way that requires the fewest steps to reach the end result, but if a from transformation has been declared in the "target" class, it will always beat an as declaration in the "source" class. This allows classes to have the definitive say in how they are instantiated.


Log In to Comment


Login / Edit User Info -- Copyright © 2002 Cognitivity -- Previous Page   Next Page