FredOoo wrote: ↑06 Aug 2020, 17:35
This is a simple ClassObject with a property
name
sure but note
E1.name on a line on its own written like this is the invocation of the method
.name() passing 0(1
* - the
this) params, and
not property access(
get). largely pedantry, but lets be clear about this
This is a simple ClassObject with a pseudo-private property _name
the
underscore-identifier is just a convention, its the backing field to a dynamic property. in AHK, there's no such thing as private(pseudo or otherwise) on account of access specifiers not existing. more pedantry
Now I want to create a ClassObject who has the ability to « decide what happens when an undefined property is invoked ».
...
It's not simply the same thing as writing in a property like in previous examples. I can write in a more complexe data structure, or deal with a iniFile…
In reality, I didn't create yet any new properties in meta-methods. I created new items in the list property named PROPS.
ok, its what u chose to do - not to define properties but rather store them in a Map. so?
But I destroyed my ability as a developer, to talk about that very well know property called PROPS, and defined as a Map.
??? u
"destroyed ur ability as a developer to talk about the very well known property called PROPS"... i have no idea what this is supposed to mean
I had to strongly hard code it with that not friendly syntaxe this.defineProp( 'PROPS', { value: Map() } ) while it's not an unpredictble property. It's a very well known property, except of course on the left side of the affectation.
the alternative to this being the
very friendly syntaxe ObjRawSet(this, 'PROPS', Map()) - quite the difference, really...oh wait, but that wouldnt allow us to define dynamic properties, so we need it to either support an object(
ObjRawSet(this, 'PROPS', {Value: Map()})) or a new function altogether(
ObjRawSetDynamic(this, 'PROPS', getterFuncObj, setterFuncObj)). there, much better
/s
also ???? what was the point of this sentence(other than to clamor about
.DefineProps purported unfriendliness, if any)
When I say this.PROPS := Map() inside the class definition (not only the constructor), I think I give it a name (PROPS) and a value (an empty Map), a type (the type of Map) and a scope (the class object). It is not only well known, it is famous ! Everybody knows what I'm talking about, and specially the class object I'm writing in.
Later if from outside the class I invoke E3.myNameIsWho ? E3.myNameIsWhat ? that's an undetermined propery and it's a good thing if I can write a class that knows how to deal with.
"famous" properties? what? just more ?????
But to give this class the ability to respond to unknown properties, I'll first have to rewrite all the definitions of the well known properties
I think that's not fair.
ull have to rewrite all the definitions of the well known properties... just more ??????? i have no idea what ure trying to say. what are u trying to say?
Now, what if I really want to create new properties dynamically ?
ud use
Object.%Expression% := Value or
.DefineProp(), u dont need metafunctions to do that. ur code example would have been the answer to "Now, what i really want to handle the creation/access of unknown/undefined properties in a special way?", except u didnt ask this question. also, in the metafunctions, u dont need to check if the property exists - if it did, the metafunction wouldnt have been invoked in the first place.
The nice thing here is that there is no more data structure except the new properties are dynamically stored in the class as if they where declared with this.anyname := 666 and this.anotherOne := 777.
But before that it will be necessary to pull your hair to rewrite all the known properties of the class…
rewrite all the known properties of the class… more ???????? we're up to 8 of them now
Code: Select all
...
createProp( name, value:='unset' ){ ; if I use unset keyword, I can't use it
....
what do u mean u cant use it? declare the optional parameter's default to be
unset, then test with
IsSet() whether something was passed to this parameter, then u can decide whether to "use it" or not. of course, if "using it" means assigning a plain string to it(
'unset'), then it makes little sense to use the
unset/IsSet() combo - u can define primitives to be the default of parameter in the function definition already!(what u
cant declare default, is all other stuff: objects, arrays, taking other code paths, etc... This is the purpose of
unset - to unambiguously identify whether the caller used the optional parameter to pass a value in)
Code: Select all
...
this.DefineProp( name, {
; Doc: An object with one of the following own properties, or both Get and Set:
get: CProp.new(), ; function object to call
set: CProp.new() ; It's just… I don't know how to write it
; I should write set: CProp.new( value ) ??
} )
...
class CProp {
...
__call( self, val :=unset ){
...
}
}
as long as u define an appropriate constructor(with the correct number of parameters), u can write whatever u want, including
... set: CProp.new( value ) }
Code: Select all
F7.anyname := 777 ; Does it works ??
it "works", insofar as defining a property called
anyname on the object
F7, which has been instantiated from the class template
CF7. it
does not assign
777 to anything, in fact, it discards this value(u arent doing anything with it anywhere).
Code: Select all
F7.anyname ; Error: This value of type "CF7" has no poperty named anyname
again, this usage is invoking the method
.anyname() with 0 params, but lets ignore that and assume ure actually
getting the property's value.
- for the getter, u had assigned an object, instantiated from the class template CProp - a function object to call, so to speak.
- the property's getter will now attempt to invoke said function object, ie the equivalent of %instanceOfCProp%(F7, 'anyname').
- having thoroughly read the half-a-paragraph on metafunctions in the documentation, im sure ull recall that "obj.unk() invokes __Call", whereas "%x%(): Calling the object itself only invokes the Call method. This includes internal calls made by built-in functions such as SetTimer and Hotkey."
- well, ur function object doesnt appear to have a Call method defined on it. the invocation fails, u get an error thrown
the only point of contention here is whether the error message fits or not.
on one hand, u could have gotten the standard
"This value of type ???(in ur case CProp, the instantiated funcObj) doesnt have a method named 'Call'". this might be confusing in the context of properties
on the other hand, ur
are getting a more relevant, albeit incorrect(with respect to the property having been defined, since it truly is defined - its just that its absolutely unusable thereafter), message
"This value of type "CF7" has no property named 'anyname'"
regardless of the nature of the message, there is a semantic error - namely, ur function object not being an
actual function object(on account of not having a
Call method. again read the docs:
"User-defined function objects must define a Call method ...")
Here v2 is not anymore a simple modernization of the horrible old v1 syntaxe. It's the project of a new language. An interesting project but creating new syntax difficulties until it is finished.
wrong. anonymous functions is the only "new language" feature. otherwise, its a modernization of the horrible old v1 syntaxe:
- commands -> functions
- hotkeys -> functions
- gui commands -> gui object model
any other remaining changes relate to:
- internals(optimizations, data structures, parser changes, type checking, saner separated prototypal model, ridding the codebase of v1 idiosyncrasies)
- error reporting(self explanatory)
- streamlining usage(eg ComCall, #DllLoad etc)
as a matter of fact, nothing about these examples
cant be reimplemented in v1. the only difference is, unless u a priori knew how to do it, owing to v1's 1% error-reporting and 99% error-suppression, u would have wasted a lot more time doing it(and u probably wouldnt have managed to do it correctly anyway. or worse yet, u wouldnt have even known it wasnt correct to begin with). with v2, at least u know theres a problem as soon as u hit run, so u can go fix it.
Now, tell this people they should bypass v1 to enjoy the v2 flexibility.
they should