About meta-functions change, Properties?

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

About meta-functions change, Properties?

06 Aug 2014, 08:09

All in top post, a little long, need well organize.

I see lexikos' opinion at v1.1.16 alpha - Properties.
lexikos wrote:the only satisfactory answer I came up with was to reduce the need for meta-functions - by implementing Properties
I don't know your counter-example. I hope you are not meaning to disable meta-function.
I haven't thought these carefully. Some discussion would be nice. :shifty:

In my point, meta-function could support basic event on read/write/call variable of object.(only consider variables that invoke meta-function)
It's as basic as key button down/up. Class is just a template with event entrance, property is similar.
With these, user can simulate property / inherit / prototype-based class / object dot syntax (use read / write operate to invoke function) / public and private etc.
Some complexity comes from various variable accesses with one entrance (such as k1, k2, kn in __Get(k)).
For this case, a distribute/routine/filter mechanism/process is needed, maybe a multi-level filter to deal with various variable accesses. Or just about lexikos's new property?
We can handle well with one complex property, so why can't multiple. :think:

I think

Code: Select all

property{
	get{
	}
	set{
	}
}
is a syntax integrate meta-function, but break consistency. A new Property Objects is added?
Coco wrote:the purpose of Properties is to provide a user-friendly interface to users who want implement some sort of dynamic get / set behavior. __Get, __Set will still be available for dynamic properties -> key name(s) that you don't know in advance.
So I write a simple routine.
See post below with a AHK V1 demo.
Another simple custom property lib which look like a real property in this topic.

Code: Select all

class c{
	__Get(k){
		if PropertyOnGet(this,k,v)
			return v
		;..
	}
	;One simple implement
	class OnGet{
		Key1(){
		}
	}
	;Or in key's view
	class 	Key1{
		OnGet(){
		}
	}
}
PropertyOnGet(o,k,ByRef v){
		Property[this][k].OnGet(v)
		;Change/Divide process to object based function.
		;Maybe just a sub class/method of class "c" above.
}
If there is a pseudo-keyword like Base (I called Self in post new pseudo-keyword like Base used in class method), it would be more flexible.


I don't favour _(uderscore) prefix (i.e. MyProperty for interface key name, and _MyProperty for inner key name of value), it's just a non-compulsory protocol, like key word base - a normal key name or base which means prototype-based.
There will be ambiguity sometime, when key is a string with _ prefix.
lexikos wrote:this._myProperty is just another field where I happened to store the value. AutoHotkey does not make any connection between it and the property.
coco wrote:That was just lexikos' example, you don't have to follow it.
I think a simple / basic rule is better than various syntax / form.
Some suggestion / guide / classic usage with rule would be more flexible and practical.
User can write / select their own template to handle property.
Also, I hope everything could be referenced / involved and changeable dynamic.
And avoid representation from becoming fixed and unchangeable.

I write this thread hastily, without careful consideration.
I'm anxious about "reduce the need for meta-functions". :|
Last edited by RobertL on 02 Sep 2014, 10:48, edited 13 times in total.
我为人人,人人为己?
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: About meta-functions change in V2

06 Aug 2014, 08:44

RobertL wrote:I hope you are not meaning to disable meta-function.
RobertL wrote:I'm anxious about "reduce the need for meta-functions".
I don't think that meta-functions will be removed. From my understanding, the purpose of Properties is to provide a user-friendly interface to users who want implement some sort of dynamic get / set behavior. __Get, __Set will still be available for dynamic properties -> key name(s) that you don't know in advance.
RobertL wrote:I don't favour _(uderscore) prefix (i.e. MyProperty for interface key name, and _MyProperty for inner key name of value)
That was just lexikos' example, you don't have to follow it.
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: About meta-functions change in V2

06 Aug 2014, 09:22

Coco wrote:the purpose of Properties is to provide a user-friendly interface to users who want implement some sort of dynamic get / set behavior. __Get, __Set will still be available for dynamic properties -> key name(s) that you don't know in advance.
I have update my post ,see "I write a simple routine".
I don't realize other advantages of Property.
我为人人,人人为己?
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: About meta-functions change, Properties?

06 Aug 2014, 09:46

The thing with __Get and __Set is the learning curve for users who are exploring the functionality, especially to those who have no prior experience with something similar. While on the other hand, Properties is so easy to understand, it almost looks like pseudo-code, one glance and you get what it does. Code maintainability comes into play as well.
Here's an alternative way to handle __Get: from the help file

Code: Select all

blue := new Color(0x0000ff)
MsgBox % blue.R "," blue.G "," blue.B

class Properties
{
    __Call(aTarget, aName, aParams*)
    {
        ; If this Properties object contains a definition for this half-property, call it.
        ; Take care not to use this.HasKey(aName), since that would recurse into __Call.
        if IsObject(aTarget) && ObjHasKey(this, aName)
            return this[aName].(aTarget, aParams*)
    }
}

class Color
{
    __New(aRGB)
    {
        this.RGB := aRGB
    }

    class __Get extends Properties
    {
        R() {
            return (this.RGB >> 16) & 255
        }
        G() {
            return (this.RGB >> 8) & 255
        }
        B() {
            return this.RGB & 255
        }
    }

    ;...
}
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: About meta-functions change, Properties?

06 Aug 2014, 09:53

@Coco
Yes, a choice between depth and width.
I would prefer a simple / basic rule than various syntax / form.
Hope my template/routine is clear and easy to understand.

I think the example from help is a little difficult, a frame mechanism may be emphasize / learned first, then simple application.
Otherwise, learner would apply mechanically.
Last edited by RobertL on 06 Aug 2014, 09:59, edited 1 time in total.
我为人人,人人为己?
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: About meta-functions change, Properties?

06 Aug 2014, 09:59

Your routine will look daunting to new users diving into meta-functions compared to:

Code: Select all

MsgBox % Ahk.version
MsgBox % Ahk.website
MsgBox % Ahk.forums

class AutoHotkey
{
    version {
        get {
            return A_AhkVersion
        }

        set {
            throw "This property is read-only"
        }
    }

    website {
        get {
            return "http://ahkscript.org"
        }
    }

    forums {
        get {
            return "http://ahkscript.org/boards"
        }
    }
}

class Ahk extends AutoHotkey
{
    __New() {
        return false
    }
}
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: About meta-functions change, Properties?

06 Aug 2014, 10:02

The key here is to reduce the need for meta-functions, but it doesn't mean that you can't use them. __Get, __Set will still be available for more complex requirement(s)
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: About meta-functions change, Properties?

06 Aug 2014, 10:05

@Coco
It seems so :problem:
Your example is more clear.Thanks~
我为人人,人人为己?
toralf
Posts: 868
Joined: 27 Apr 2014, 21:08
Location: Germany

Re: About meta-functions change, Properties?

06 Aug 2014, 10:18

I like your exmaple, because it explains very simple properties, nearly too simple.
Could you please extend your example?
a) to be able to set a property to a different value, e.g. the website
b) have a property, that does some function before it returns something, e.g. a property "all" that returns an array of version, website and forum.
c) and a method, e.g. that opens either website or forum.

I hope that this would then cover most of the functionality offered by a class. If I have forgotten some feature, please extend the example. Much appreciated.
ciao
toralf
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: About meta-functions change, Properties?

06 Aug 2014, 11:55

like toralf, i'm looking forward to seeing extended examples for usage of the new Properties and when/why they may be used

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: About meta-functions change, Properties?

06 Aug 2014, 14:00

guest3456 wrote:like toralf, i'm looking forward to seeing extended examples for usage of the new Properties and when/why they may be used
Can't come up with anything cool, I'm pretty sure other(s) will have better examples...

Code: Select all

jrnl := new Journal ;// Create the journal
jrnl.entry["my_thoughts"] := "The quick brown fox jumps over the lazy dog."
MsgBox % jrnl.entry["my_thoughts"] ;// get entry
jrnl.entry["another_thought"] := "AutoHotkey" ;// Add another entry
jrnl.entry["my_thoughts"] := "" ;// Delete entry
my_thoughts := jrnl.entry["my_thoughts"] ;// No longer exists
MsgBox % jrnl.entry["another_thought"]
MsgBox % jrnl.entry["another_thought", "date_created"] ;// date created
MsgBox % jrnl.count ;// total number of entries
return

class Journal
{
	__New() {
		this.db := {}
	}
	;// nice feature, ability to set default value for a particular key's param
	;// with __Get, this is cumbersome
	entry[name, field:="contents"] {
		get {
			if !this.count {
				MsgBox You have no entries yet.
				return
			}

			if !ObjHasKey(this.db, name) {
				MsgBox No such entry exists: %name%
				return
			}
			return this.db[name][field]
		}

		set {
			exists := ObjHasKey(this.db, name)
			if (exists && value == "")
				return this.db.Remove(name)
			entry := {
			(LTrim Join
				"contents": value,
				"date_created":  exists ? this.db[name, "date_created"] : A_Now,
				"date_modified": A_Now
			)}
			this.db.Insert(name, entry)
			return value
		}
	}

	count {
		get {
			return NumGet(&(this.db)+4*A_PtrSize)
		}
	}
}
The thing about Properties,I don't have to do a bunch of if (key = "some_key"), do this; else if (key = "another_key"), do that
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

A demo withing basic class instead of property in AHK V1

06 Aug 2014, 19:38

Your (@Coco) example is vivid / clear and practical.
But I think the key / advantage of property is its simple entrance of of every property.

A demo of simple routine/wrap, using AHK V1 code, run it, then expand it.
I think it's easy to implement all the feature of example above. :?:

Code: Select all

class c{
	__Get(k){
		;This is a common template.
		;could support more parameter like 'field'.
		self:=c	;Handle it manual, explain it below.
		if ObjHasKey(self,k)
			return self[k].OnGet()
		if ObjHasKey(self,"OnGet")
			return (self.OnGet)[k]()
		;Then default behavior.
		;or something else.
	}
	class SomeKey{
		static value:="Default"
		static CountOfAccess:=0
		OnGet(){
			self:=c.SomeKey	;'Self' should be a relative anchor like 'base', I handle it manual currently.
			self.CountOfAccess--
			return "From special OnGet of 'SomeKey'.`nThe value is:" self.value "`nCurrent count of access:" self.CountOfAccess
		}
	}
	class OnGet extends c.OnGet.Default{
			;could use 'self.Default' if 'self' supportted
		AnotherKey(){
			return "From general OnGet which could handle 'AnotherKey'."
		}
		class Default{
			__Call(k){
				return "There's no process to handle the key:" k
			}
		}
	}
}
o:=new c
MsgBox % o.SomeKey
MsgBox % o.AnotherKey
MsgBox % o.OhterCases
ExitApp
There is room for improvement, using object dot syntax and inheritance.
self is a pseudo-keyword like Base.
It will pass this through self.xx/self[xx] as the same as Base.
But it point/refference to the object (class) of which contains the current method.
See new pseudo-keyword like Base used in class method.
Coco wrote:if (key = "some_key"), do this; else if (key = "another_key"), do that
Try to use object, such like RoutineMap[AnyKey]-AssociateHandleProcess.
我为人人,人人为己?
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: About meta-functions change, Properties?

06 Aug 2014, 22:30

I wrote some ideas for meta-functions in v2-thoughts, but my current tentative plan is this:

obj[key], obj[key] := value, obj[key](), obj.literal_key(), etc.
  • If the key exists in obj or obj has no base, do as in v1. Otherwise:
  • If a meta-method is defined, call it.
    • Inheritance is explicit - like v := base.__Get(key) or similar. This way it has full control over the behaviour, and acts the way a method should act. If there's no super-class or if none of the super-classes define that meta-method, the built-in behaviour is called instead (returning a static/class variable or calling a property or method). A class can make its own static variables take priority by checking ObjHasKey() before calling base.
    • The return value becomes the result of the get/set/call expression, as before.
    • base.__Call(key) would throw an exception if the method isn't implemented, since that's the default behaviour. Try can be used to detect this. For properties, you would have to find some other way of determining if a value was actually defined (if you needed to know and the base returned "").
    • Method definition syntax (all parameters are optional):

      Code: Select all

      __Get(keys)  ; Key parameters can be listed individually or declared as variadic*
      __Set(value, keys)  ; value first is more convenient for variadic methods, or just so you can ignore parameters.
      __Call(key, parameters)
  • If no meta-method is defined, inherit values or call Properties or methods as in v1.
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Brief summary

06 Aug 2014, 23:23

v2-thoughts is so long and topic-mixed, and is hard for someone (only me?) to follow. - v2-thoughts is a good resume!
Fourm (also this thread) has litimted, which has a bias towards procedure of discussion , not the result/conclusion.
What about arrange them to something like Wiki, or just create a new topic version 2.0. :?:

Can somebody summaries with comparing the v1 one?
I don't find much different, not see any Property, is this a good news? :?
property is a package of singleton sub class (without class key word declaration) (or better any normal object I hope), what my demo shows.
Moreover, its data belong to instance.

Also, I look forward to pseudo-keyword Self, function ObjGet/SetRawBase.
See example in post above.

Append:
I don't agree to add new element / concept which is away from innate character. A little convention, but more confusion. (Maybe I was fear about new thing)
Means Property Object is physically a normal object (I think specific a sub class with pre-defined method, so it would be easy to implement, also see the example above) which is / used in the new property mechanism.
我为人人,人人为己?
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

My simple custom property lib.

02 Sep 2014, 10:14

My simple custom property lib which look like a real property. Extemporaneous work.

Code: Select all

o:=new c
o.NormalMember:=1
o.PropertyMember:=2
MsgBox % o.PropertyMember	;3
ExitApp
;--------------------PropertyMember--------------------
class c{
	class PropertyMember{	;Custom Property
		static _Property:=True	;A mark not necessary 
		Get(){
			return base.value+this.NormalMember
		}
		Set(v){
			return c.PropertyMember.base.value:=v
			;	return base.value:=v	;This can't work? foget, maybe one more object level
		}
	}
	__Get(k){
		if k!="base" && __Property[this](k,v:=__Property)	;Watch read on property.
			return v				;If a property
		;Other case which is not a property.
		;...
	}
	__Set(k,v){
		if k!="base" && __Property[this](k,v)	;Watch write on property.
			return v				;If a property
		;Other case which is not a property.
		;...
	}
}
;==================== Lib ====================
class __Property extends __Property.B{
	static PropertyInstance:={}	;Store PropertyForInstance date.
	;Lack on release, big problem, the instance should hold their own Property date, while there is no weak refference (can be simulate.)
	class B{
		__Call(onwer,k,ByRef v){
			if !((_:=onwer.base) && (_:=_[k]) && (_._Property))	;A GetObjBase is needed.
				return	false	;Not a property
			;A property
			propertyHandle:=onwer.base[k]
				;	if !__Property.PropertyInstance[onwer]
				;		__Property.PropertyInstance[onwer]:={}
			if !__Property.PropertyInstance[onwer,k]
				__Property.PropertyInstance[onwer,k]:={value:""}
			propertyHandle.base:=__Property.PropertyInstance[onwer,k]	;A temporary channel
			;There is a way to use instance object's 'base' in Property as normal pseudo-keyword 'base', so only override the 'value'.
			if(v=__Property){	;Read
				_:=onwer.base[k].Get
				v:=%_%(onwer)
			}else{				;Write
				_:=onwer.base[k].Set
				v:=%_%(onwer,v)
			}
			propertyHandle.base:=""	;Delete channel.
			return true
		}
	}
}
However, I like your other plan.
Relative to topic v1.1.16 alpha - Properties
Last edited by RobertL on 02 Sep 2014, 18:58, edited 2 times in total.
我为人人,人人为己?
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: My simple custom property lib.

02 Sep 2014, 12:50

RobertL wrote:My simple custom property lib
simple? heh

lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: About meta-functions change, Properties?

02 Sep 2014, 16:23

if !__Property.PropertyInstance.onwer
__Property.PropertyInstance[onwer]:={}
This is probably not what you intended: .onwer and [onwer] are two different keys. However, it's unnecessary since x[onwer,k] := ... will initialize x[onwer] automatically. Also, you might mean "owner".
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

Re: About meta-functions change, Properties?

02 Sep 2014, 18:50

@guest3456
With the lib, means create customer property will be easy, and much more flexible, only a little more code to add to a noraml class who want to add property, which could use template to insert.

@lexikos
Sorry, I mixed them. I had afraid x:=t[NotExistMenberA,NotExistMenberB] will cause No object to invoke error(tested wont be), and I write the code in a hurry.
Thanks to point out.
Also, there is a way to use instance object's base in Property as normal pseudo-keyword base, so only override the value.
我为人人,人人为己?
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: About meta-functions change, Properties?

02 Sep 2014, 19:58

I'm not sure what you're asking, but
I wrote:The object's base can't be accessed this way. If you defined a property named base (with getter), the object's base would be inaccessible because this.base invokes the property.
http://ahkscript.org/boards/viewtopic.php?f=24&t=4135
User avatar
RobertL
Posts: 546
Joined: 18 Jan 2014, 01:14
Location: China

My demo and opinion

02 Sep 2014, 20:39

@lexikos
"base" has ambiguity, means class, or key named "base". Can't avoid.
So, I (had) suggest to add a third party funtion ObjGet/SetBase() (In Lua, it use get/setMetatable), could also maintain "base" as an easy way to access class.

I think "Overriding Properties" in your link can be implemented, by adding some condition in the demo.


You talk about this?
Use instance object's base in Property as normal pseudo-keyword base, so only override the value.
Presupposition, there is no ambiguity on using "base".
In my property class, can use this / base (not implement) as normal (use base.x to access supper-base, not the Property's), except base.value is the content of current property, which may override the real key named "value" in base, however this can be avoid.


My opinion:
New feature Property is an integrate for easy use and plan to replace meta-function, which I don't know the background module - seems unknown / notransparent and mysterious, and don't sure about its major advantage over the demo above.
And I'm worry about this flexible means cross-functional, it's hard to thorough design, and must has blind angle. I want to stop you from falling into the pit. It is? :think:
我为人人,人人为己?

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Danielsan73, Insaid, just me, songdg and 42 guests