-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disambiguate Corinna from other objects #32
Comments
Data::Dumper has support for Freeze methods (see https://metacpan.org/pod/Data::Dumper#Configuration-Variables-or-Methods ), so does Storable (see https://metacpan.org/pod/Storable#STORABLE_freeze-obj,-cloning ). Cor classes could provide an overridable universal freeze method that would return a deep-cloned hashref that may be used for general purpose serialization. This mechanism also might also be useful to non-Corinna classes - eg. for inside-out classes, or classes accessing c-data structures. |
This question might or might not overlap with what happens with Moo or Moose extend a Cor based class. Will it work at all? Will Moose be able to inflate a meta object for a Cor class? If so will Cor's methods and lexical slots be inspectable as methods and attributes |
That and related questions will be up to the maintainers of Moo and Moose when Corinna is available.
Internal state needs to be exposed for debugging purposes, but not for programmatic purposes. That defeats the point of encapsulation. So we've been in discussion about making this human-readable, not not guaranteeing its format or that it can be trivially parsed. From what I understand, however, Paul Evans has talked with Data::Printer maintainers about possibly adding introspection for Object::Pad. However, all parts of the public interface should be inspectable. |
The most important thing is that these routines will return some new value that is unique to Corinna classes and has never been returned by those methods before for anything else. I think |
To go along with Corinna, Perl should globally (such as provided in |
On a tangent, with my own Muldis Data Language / Muldis Object Notation project, I have designed it such that implementations explicitly have 3 distinct methods for serializing values as character strings. Implementations can just so happen to make them produce identical output but they don't have to.
Bottom line is, in a serious language/serialization project, these are 3 very distinct use cases that should each in principle have their own serialization routines, that are free to but not required to return the same strings. |
Sounds like Str and Gist in Raku to me and yes I love those! |
Yes, that's along the lines of what I had in mind. In particular Raku's gist() is like my as_preview_string() including that the string could actually leave out details and not have to be exhaustive, eg it could limit to a maximum of 1KB rather than producing 1GB just because the structure is that big. I'm not sure how gist() is implemented but the examples I've seen suggest it swings on the side of being too terse, eg may only output 50 bytes or the first 3 list items or something. But making ours non-deterministic we can tune those things over time and not worry about having to keep it the same once set. |
Let me make sure that y'all are aware of the consequences this creates. A big part of debugging in general, across almost all languages in existence, paradigms, platforms, is to be able to use automatically updating visual representations of data which can also be used to modify memory data in realtime, and being that data can be extremely large and deep hierarchically, the norm is to do this in trees, which are loaded on-demand and just-in-time with limits on how deeply trees are loaded, to avoid parsing a 2 gigabyte object dump on every step. This is currently extremely viable in Perl as demonstrated below (there are more features and interactions not shown, but space constraints) and implemented in at least 3 editors to my knowledge and likely many more. 2022-02-21.10-51-14-1.mp4(i could've recorded the same thing in 10 different languages just with what i've installed on this machine) In general the difference between debugging and programming is about the same as between scripting and programming, which is to say it is a difference even more vague, malleable and ill-defined than genders. In addition to that, a lot of debugging techniques involve programming on the debuggable during the debugging. It is one choice to say "i am not interested, i will not use this", but it is another choice to say "i will take steps to ensure nobody else can use this". Especially so when the latter means that somebody who was previously able to fairly quickly analyze the control and data flow in a module they downloaded from CPAN may now be forced to spend considerable additional time because of somebody else's choice, or choose a different module from CPAN. If you make the choice of "nobody else can use this", please be aware that that is actually the choice you are making, and all it entails. |
@wchristian said:
@wchristian About your new response to something I wrote 5 months ago, I feel that you fundamentally misunderstand what I said, as your response is talking about completely different functionality that what I said which you quoted. My comment was about generic holistic serializations of any typed Perl value TO A SINGLE CHARACTER STRING that would be best provided built-in to Perl itself that are standard for every type. I was naming 3 very distinct use cases for which one may serialize an object, each of which would have its own needs, and each of which the serialization logic could choose to behave differently to optimize for that case. The 3 use cases are:
The text of mine that you quoted is about number 3 above, which is why I say one can't count on being able to programatically parse it meaningfully to reproduce the original value, because that isn't what its for. Given some typical GUI debugger when your program is paused and you are inspecting variables, if you hover over some variable and there is pop-up text showing its contents, that pop-up is likely to only show the first few hundred bytes, a preview, and not try to generate a gigabyte of text. This preview is what my number 3 is for. What YOU seem to be talking about is NOT everything-into-a-string, instead you are examining values as structures and letting one look into the parts, it is NOT turning everything into a string. So please clarify what the problem is that you seem to have with what I said, or if you no longer have a problem with it now that I've hopefully made more clear what I'm talking about. |
I came here because Ovid closed #30 and pointed at this issue. Your post seemed to be the only one with anything similar to a solution to the larger complex. If that's not intended, fine. Nevertheless, i made a video. Corinna is steering towards making what it shows impossible, i.e. towards being useless with a debugger. If that is the decision Cor makes, it needs to be an explicit one. |
@wchristian For the general case of actual live debugging we would need to have structure traversal which is separate from and in addition to any of the serialization functions I named, partly because of the need to scale. For the general case of at rest debugging, what I said does cover it, specifically the number 2, serialization for interchange or storage/retrieval. Do you agree? |
I am not married to any one particular solution*, and am currently only advocating for the premises to be determined, but that sounds reasonable, yes. * for example one possible option is to disable strict encapsulation when running under the debugger |
The way I see it, to have true complete debugging, there can't be an absolute concept of privacy. It must be possible to write arbitrary user-land code which is able to see into anything, such that all the interesting and non-trivial parts of a debugger can be written in and run in user land and do their work using ordinary system-provided APIs. There would have to be no true private anything, and privacy is advisory rather than absolute, but that the advisory privacy comes with enough barriers that one would not normally write code that bypasses them. I don't know if there's any precedent for this but I had an idea since a few years ago for designing a language such that access to privates requires shared secrets. So Perl could be run in such a way that the implementation provides a copy of say a "debugger key" to the user-written debugger program, which treats it as a data piece, and then whenever the debugger wants to view something private, it does this say using a "builtin::get_private()" routine which takes for example a few arguments that are the thing to inspect, the name of the property one wants to view, and the key. Or the debugger key could be an object and get_private() a method and so the key is implicitly provided. This idea could also be generalized to not be about debuggers specifically but just a way for various classes to manage shared secrets which include each others' privates and that can be on a per-object basis rather than for all objects of the same class. I mentioned something like this before as an alternative to having class fields. So we can have a concept of true system-enforced "unbreakable" privacy but with secured back doors for those who are allowed to see them. A real world analogy is like the special keys that firefighters have to access buildings. @wchristian So I agree that whatever you think Perl should provide so Corinna can be properly debugged, it should be there. |
The intent is to ensure that debugging is supported. Due to the dynamic nature of Perl, it will still be possible to use those same facilities for violating encapsulation in general programming, but the intent is to make that harder to do so that it doesn't become the default |
I suggest we take the current implementation of Object::Pad as an example, since it clearly demonstrates how this could work nicely. For context, let me compare it to the hash-based zoo of OO modules where Moose is a prominent example, and to the inside-out based modules like Dios. Moose-like objects do not need any special support for debugging or serializing. Blessed hash references have been around for quite some time before Moose appeared. On the downside, they are just that: Blessed hash references. They can be used as hash references from anywhere in the code base, and statements like Ovid's example Now look at Object::Pad: Its objects are immune to intrusions like So, if Corinna follows the path of Object::Pad, we should be all set. |
Generally speaking, objects should be opaque to the outside world. However, there are times that we need to know what we're working with. For example, the debugger problem means that
Data::Dumper
and friends would need some way of realizing that "hey, I can get useful state information for this thing".There's also the question of what
ref
andScalar::Util::reftype
will return.The text was updated successfully, but these errors were encountered: