2) seems the most flexible/powerful one.

Constants can be regarded as special attributes that can be accessed in the 
class object and in each
of its instances. Currently their value is a symbol.

As you are envisioning some sort of a method execution to determine the 
constant value, how about
allowing a method body (like an attribute setter method without an argument) to 
define the constant
value?

Something like:

    ::constant aconstant foo -- like now

    ::constant fullsize            -- new: no value supplied, just the name
       expose fullsize
       fullsize=2**12

    ::constant halfsize            -- new: no value supplied, just the name
       expose halfsize fullsize 
       halfsize=fullsize/2

    ::constant x_halfsize_x        -- new: no value supplied, just the name
       expose x_halfsize_x 
       x_halfsize_x= self~x_fullsize_x/2   -- employ "self"

    ::constant x_fullsize_x 4096  -- like now

    ::constant abc                -- new: no method body use name as value, 
hence will use "abc" as its constant value

---rony



On 17.12.2018 23:41, Rick McGuire wrote:
> I admit this is a feature I've wanted for some time but was not sure how to 
> actually do it. Since
> Erich opened the feature request, I thought I should give it a closer look. 
> I've gotten far enough
> into this that I believe it can be done, with some restrictions. There are a 
> few items where
> decisions need to be made on which direction to proceed. 
>
> So, basically this will work by building a special method that runs on the 
> class object during the
> package install process. Each class directive will have its own special 
> method and the
> instructions executed will be any ::constant directive that has a 
> non-constant expression value.
> There should be no restrictions on the expressions and the variables SELF and 
> SUPER will have the
> expected values for a method run on a class object. The expressions when run 
> will be traceable if
> ::options trace is used, even interactive trace. I've got most of the 
> mechanisms on how to do all
> of this worked out and it looks pretty clean. 
>
> My first thought was to apply the current rules for parsing ::CONSTANT and 
> anything that fell
> outside of the current rules would be a constant. This works, but there is a 
> gotcha. The current
> rules allow constants to be defined using 
>
> ::constant aconstant foo
>
> where foo is a symbol treated as a constant. Going this route means 
>
> ::constant aconstant self 
> ::constant anotherConstant (self)
>
> would produce different results. The parsing code could consider non-constant 
> symbols to be
> expressions, which would cause these to have the same values, and most 
> ::constant declarations
> would be unaffected because the variable would be uninitialized, and thus 
> have the same
> values...with the exception of the variables SELF and SUPER, which will have 
> a value. There's also
> the issue of ::options novalue error, which will suddenly start getting 
> tripped by instructions
> that were fine before. 
>
> Right now, I'm leaning toward an explicit syntax to indicate the value needs 
> to be computed at
> class creation time. We already have a precedent of using parens to indicate 
> a general expression,
> so I believe we should use that. No parens, old rule, in parens, an 
> expression to be evaluated. 
>
> Part of the processing I envision is the constant methods are created 
> initially, but are
> "incomplete" and if they are invoked before they are "completed", they will 
> raise a new subcode of
> error 97 to indicate the constant had not been initialized. Initialization 
> occurs in declaration
> order, so constants can refer to other constants of the same class, as long 
> as they were declared
> prior to the usage. That is
>
> ::constant fullsize (2**12)
> ::constant halfsize (self~fullsize/2)
>
> Would work, but 
>
> ::constant halfsize (self~fullsize/2)
> ::constant fullsize (2**12)
>
> would give an error evaluating self~fullsize. Directives with true constant 
> values will be
> available always, so 
>
> ::constant halfsize (self~fullsize/2)
> ::constant fullsize 4096
>
> would work because fullsize method was complete at parse time. 
>
> The next issue I'm wrestling with is when to perform the calculation. The 
> current package
> installation code does things in two passes. During parsing, the classes are 
> analyzed for
> inheritance dependencies and the classes are created so that classes that are 
> required by other
> classes are created first, so these are not done in top-down declaration 
> order.  
>
> Once all of the class objects have been created, a second pass is done to 
> call the activate()
> methods on the new class objects. 
>
> The dynamic constants (looking for a better name for these...) introduce a 
> third stage to this
> processing. I see three approaches that can be used: 
>
> 1) Completing the constants is part of the class creation, so it is done for 
> each class in turn.
> This will limit somewhat the ability to refer classes defined within the same 
> package. 
> 2) Perform a complete pass through the class objects initializing the 
> constants. This allows some
> capability to reference other classes and all of the constants are completed 
> before any of the
> activate() methods are invoked. 
> 3) Perform the constant initialization at the same time activate() is called 
> on the class. Again,
> this limits the ability of class activate() methods to use the constants 
> defined by another class. 
>
> Right now, I'm leaning toward 2), because it means the classes are all fully 
> initialized as class
> objects before any of the activate() methods are calls. 
>
> Those are the biggest issues I see here. I've got enough code roughed out to 
> believe this can
> work, but I have quite a bit more to go.
>
> Rick 
> 2) Completing

_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to