cristianbuse / VBA-WeakReference

Break Reference Cycles in VBA using simulated Weak Object References
MIT License
13 stars 5 forks source link

GPL? #1

Closed retailcoder closed 4 years ago

retailcoder commented 4 years ago

Nice implementation!

GPL is a mistake though, this code has no business being licensed under GPL - it's not software, it's more like a library, or some code snippet.

Per the terms of GPL, anyone using this in their project must also license their project under GPL and make the source code available to anyone that asks - and that sucks, unless everything you ever do is open-source; people using this code are likely going to just outright ignore the license, or dig up and use a less-optimal version of it that is more permissively licensed.

This was the original implementation and feedback, posted 2018/08/24 under CC-BY-SA (with attribution required as per Stack Exchange terms of service):

https://codereview.stackexchange.com/q/202414/23788

This article was published 2018-09-11 without an explicit license:

https://rubberduckvba.wordpress.com/2018/09/11/lazy-object-weak-reference

Also: https://www.vtsoftware.co.uk/tools/weakreference.cls

Consider switching to an MIT license, GPL isn't appropriate for this.

cristianbuse commented 4 years ago

Thanks for taking the time to explain. Needless to say I haven't read the license(s) in full. It's time I did.

By looking at the first 2 links it seems to me that you are the author of both. So I do not understand your initial (edited out) statement: "I don't care that people take my VBA stuff, make it better and then claim it as their own", since it's still you. Were you reffering to the general idea of the MIT license?

I also do not care about who or how uses this particular code or any other VBA repositories I have posted. So MIT seems the way to go. I will read the licenses and update accordingly. Thanks!

cristianbuse commented 4 years ago

Since you have not replied to my question, I have decided to read your initial comment again.

Here is what I think.

By writing “I don't care that people take my VBA stuff, make it better and then claim it as their own - your implementation looks more robust” I believe you have insinuated that I have done just that i.e. take your stuff.

I did not know how to react to this. Since I respect your work and contribution to the VBA community (Rubberduck which I have used), I decided to write the below which I hope you will read.

Because I named my class/repository “WeakReference”? I learned about Weak References by coding in Swift. See my commits here: https://github.com/hansguntersson/DDE-xcode/commits?author=cristianbuse.

Because I left a comment on your article saying “Thank you”? The only reason I posted a comment on your article was so that people can find my solution. Basically, I wanted to take advantage of your article’s page ranking on Google (first on my browser). I viewed it as advertisement.

Because I used “RtlMoveMemory” API? The idea that you can use “CopyMemory” API to get an Object from a memory address is something that I first saw in 2017, here: https://www.rondebruin.nl/win/s2/win015.htm. I believe article is dated 2011 (downloadable file certainly is). I used the idea over the last years to retrieve the Excel Ribbon after loss of state (which is safe as there will always be a Ribbon Object in memory while the host Application is running, Excel in my case). I could have used the same code wrapped in a class to get something similar with what you have mentioned in your 2018 article. That is, I knew this before you wrote it. I did not use this approach because it crashes the host Application if the memory pointer is invalid and I saw no way to check if the memory address is still valid without using APIs like “IsBadReadPtr” which is obsolete. Also, slow if called many times.

Until a month ago, I continued to break reference cycles manually in VBA by using a “TerminateRefs” method in the “child” class that is called before the “parent” is set to nothing. Crude and still prone to leaks as state could be lost before the method is called. But faster than the copy memory approach.

I spent a couple of weeks trying to find a decent workaround for a x64 bug with the custom class enumerations in VBA (i.e. marking a method/property with attribute -4 (DISPID_NEWENUM) so that the class can be iterated using For Each … Next) which I still have not figured how to avoid yet (you are probably not aware of this bug – I can expand – it probably affects your work as well) and accidently stumbled across the “VariantCopy” function which intrigued me.

I started reading a lot about Variant and then a lot about COM. And then while re-reading the same documents (mainly Microsoft docs sites) repeatedly I came up with the idea that I could retrieve an object from its memory address by using Variants and manipulating the VarType. Of course, this was exciting for me. I quickly put everything else on hold and started looking into my idea.

Initially I used a faked Variant/String by manipulating a remote BSTR structure (faked of course with a Long for Length, an Integer for the VarType acting as a 2-byte character and a trailing Null) to change the data type of a Long to Object (by assigning character codes corresponding to the desired VarType) and that worked but in certain cases was still crashing Excel (the Application I was testing on) because when strings in VBA (pointers to BSTR structures) go out of scope, memory is still reclaimed. I wasn’t aware of the VT_BYREF flag back then.

And then I remembered seeing the VT_BYREF flag when reading about Variants. I imagined that I could use it outside of a method scope and then started testing the idea. It worked.

It took me 2-3 weeks to do this (more than 100 hours) all on my own reading Microsoft documentation (which I have referenced in the class) and about COM to even come up with the ideas. Not to mention testing all the dead ends. All code written from scratch.

I was not even planning to create a Weak Reference class. It just happened.

I have mentioned the technique (copying 4/8 bytes – a memory address - into a temporary object) you also happened to use, in the introduction section of my code as “The easiest solution (not the one implemented in this class…”. I have also explained why it is not used.

My solution is unique, and the idea came naturally by going through the steps mentioned above. Moreover, the remote VT approach solved the case when the referenced object has been already erased so that the Weak Reference class returns Nothing without ever crashing.

I, for certain, did not learn/heard about the Weak Reference concept from you or your articles. Same applies for copying the address bytes into a temporary uncounted/unmanaged Object to get the referenced Object back by using CopyMemory API (not even used in my repository).

I was astonished by your suggestion that I improved on your “VBA stuff”. It is clearly a different beast. Yes, I took advantage of your article to get publicity (if you want to call it that way). I see no harm in that.

I believe that you should keep my comment on your article (https://rubberduckvba.wordpress.com/2018/09/11/lazy-object-weak-reference/) because it has the same purpose as your work. To help others.

retailcoder commented 4 years ago

I'm sorry I initially posted that original comment without first seeing the code; I did the only sensible thing to do: retract, and now apologize.

Your work is truly impressive, outstandingly researched, and I'll definitely keep your link/comment up!

I've had other code outright ripped off CC-BY-SA on Code Review before, unilaterally relicensed and all rights claimed without a shred of credit anywhere. I make everything I do public and permissively licensed, up for grabs if you will, but a permissive license doesn't equate public domain.

Again, I'm sorry I wrongly assumed that's what was going on here, and hope the people that use your code and build on top of your work and research, respect your license terms - GPL makes that hard to do though!

Cheers!

On Thu., Jul. 9, 2020, 01:51 Cristian Buse, notifications@github.com wrote:

Since you have not replied to my question, I have decided to read your initial comment again.

Here is what I think.

By writing “I don't care that people take my VBA stuff, make it better and then claim it as their own - your implementation looks more robust” I believe you have insinuated that I have done just that i.e. take your stuff.

I did not know how to react to this. Since I respect your work and contribution to the VBA community (Rubberduck which I have used), I decided to write the below which I hope you will read.

Because I named my class/repository “WeakReference”? I learned about Weak References by coding in Swift. See my commits here: https://github.com/hansguntersson/DDE-xcode/commits?author=cristianbuse.

Because I left a comment on your article saying “Thank you”? The only reason I posted a comment on your article was so that people can find my solution. Basically, I wanted to take advantage of your article’s page ranking on Google (first on my browser). I viewed it as advertisement.

Because I used “RtlMoveMemory” API? The idea that you can use “CopyMemory” API to get an Object from a memory address is something that I first saw in 2017, here: https://www.rondebruin.nl/win/s2/win015.htm. I believe article is dated 2011 (downloadable file certainly is). I used the idea over the last years to retrieve the Excel Ribbon after loss of state (which is safe as there will always be a Ribbon Object in memory while the host Application is running, Excel in my case). I could have used the same code wrapped in a class to get something similar with what you have mentioned in your 2018 article. That is, I knew this before you wrote it. I did not use this approach because it crashes the host Application if the memory pointer is invalid and I saw no way to check if the memory address is still valid without using APIs like “IsBadReadPtr” which is obsolete. Also, slow if called many times.

Until a month ago, I continued to break reference cycles manually in VBA by using a “TerminateRefs” method in the “child” class that is called before the “parent” is set to nothing. Crude and still prone to leaks as state could be lost before the method is called. But faster than the copy memory approach.

I spent a couple of weeks trying to find a decent workaround for a x64 bug with the custom class enumerations in VBA (i.e. marking a method/property with attribute -4 (DISPID_NEWENUM) so that the class can be iterated using For Each … Next) which I still have not figured how to avoid yet (you are probably not aware of this bug – I can expand – it probably affects your work as well) and accidently stumbled across the “VariantCopy” function which intrigued me.

I started reading a lot about Variant and then a lot about COM. And then while re-reading the same documents (mainly Microsoft docs sites) repeatedly I came up with the idea that I could retrieve an object from its memory address by using Variants and manipulating the VarType. Of course, this was exciting for me. I quickly put everything else on hold and started looking into my idea.

Initially I used a faked Variant/String by manipulating a remote BSTR structure (faked of course with a Long for Length, an Integer for the VarType acting as a 2-byte character and a trailing Null) to change the data type of a Long to Object (by assigning character codes corresponding to the desired VarType) and that worked but in certain cases was still crashing Excel (the Application I was testing on) because when strings in VBA (pointers to BSTR structures) go out of scope, memory is still reclaimed. I wasn’t aware of the VT_BYREF flag back then.

And then I remembered seeing the VT_BYREF flag when reading about Variants. I imagined that I could use it outside of a method scope and then started testing the idea. It worked.

It took me 2-3 weeks to do this (more than 100 hours) all on my own reading Microsoft documentation (which I have referenced in the class) and about COM to even come up with the ideas. Not to mention testing all the dead ends. All code written from scratch.

I was not even planning to create a Weak Reference class. It just happened.

I have mentioned the technique (copying 4/8 bytes – a memory address - into a temporary object) you also happened to use, in the introduction section of my code as “The easiest solution (not the one implemented in this class…”. I have also explained why it is not used.

My solution is unique, and the idea came naturally by going through the steps mentioned above. Moreover, the remote VT approach solved the case when the referenced object has been already erased so that the Weak Reference class returns Nothing without ever crashing.

I, for certain, did not learn/heard about the Weak Reference concept from you or your articles. Same applies for copying the address bytes into a temporary uncounted/unmanaged Object to get the referenced Object back by using CopyMemory API (not even used in my repository).

I was astonished by your suggestion that I improved on your “VBA stuff”. It is clearly a different beast. Yes, I took advantage of your article to get publicity (if you want to call it that way). I see no harm in that.

I believe that you should keep my comment on your article ( https://rubberduckvba.wordpress.com/2018/09/11/lazy-object-weak-reference/) because it has the same purpose as your work. To help others.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/cristianbuse/VBA-WeakReference/issues/1#issuecomment-655916481, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABL4HBBJRY6HQGNLNZMH2Y3R2VLHJANCNFSM4OTVZJ7Q .

cristianbuse commented 4 years ago

Thanks Mathieu!

It means a lot to me. You are somebody I look up to. I am really glad you do not have a bad impression about me.

I've just updated all my repositories to MIT license. Thanks for your time!

Sincerely, Cristian

cristianbuse commented 4 years ago

I'm not sure you remember this, but I did mention a certain bug here and I am sure you've read my comment. I did not say more back then, except "it probably affects your work as well". Well, I've managed to get some time to write about it. I could surely use your vast expertise on this. Question is on Stack

cristianbuse commented 4 years ago

Hi again Matt. Apologies I keep pinging you here. I have another issue with VBA that I belive you will find interesting. Question on Stack.

Is there another way I could use to reach you in the future? Also, please let me know if you would like me to stop pinging you!

Thanks!

retailcoder commented 4 years ago

@cristianbuse no problem whatsoever! I get the email notifications and read them always, although I might not have the time to respond (or might forget to do it later... my apologies); this experimentation and research you're doing is very helpful in many ways, and I'm keeping an eye on these posts, so thanks for these pings - I likely wouldn't have seen that SO post for a couple more days, if at all!

That said if you want you can contact me by email at rubberduckvba@gmail.com. Cheers!

cristianbuse commented 4 years ago

Great. Will use the email from now on. Many thanks! Cheers!