Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
I don't understand WHY would you want the ever-changing globals. The whole idea of "current buffer" sounds a little silly to me. (No offence meant!) Why would you want to restrict yourself to one "current" buffer, having to "switch" buffers, having to remember in what part of the program the variables point to this buffer and when to the other?

I can assure you that in practice it is never any problem to remember what buffer you are working with if it matters; *usually* it doesn't matter, because most of what you want to do you want to do in a buffer-agnostic fashion.

The advantage of buffer-local variables is much the same as the advantage of dynamically scoped ("local" in Perl5, temporized in Perl6) variables: you can customise another package's behavior when it works with your data, without worrying about the effects leaking out when a third package uses your stuff and also uses directly the package you're customising.

Let's say you're writing a CSS parser, for instance. Now, the CSS parser needs to hang the style information on a DOM, so your CSS parser is going to require a DOM package of some kind, of course. But you want the DOM package to behave in a certain way. So you temporize some of its package variables. But when someone else writes an HTML parser, he'll be using your CSS parser, but he'll _also_ want to use the DOM stuff. So he'll require both. But your changes to the DOM package stuff won't have an impact on his use of the DOM stuff. Now, all of that can be achieved with temp (local in Perl5), but when you start doing somewhat more complex things, it's handy if a single package can customize the behavior of another package in several different ways for various hunks of data. For example, an OpenOffice document parser might customise the XML parsing stuff differently for content.xml versus how it wants things done for styles.xml, or whatever. (This is a contrived example, because all the good already-implemented examples are Emacs stuff.)

The whole point, in fact, of buffer-localisation of variables is that you don't need to keep track of what buffer you're using when (and a sub can use different buffers at different times), because each buffer can carry its stuff (in this case, customisations of other packages' vars) along with it.

Yes, it could be done just by attaching a hash of customisations to each buffer, but then all the packages that you might want to customise would have to be aware of and pay attention to such things, which would be a major pain.

Now, all up to this point I've been talking about the semantics of make-local-variable, which simply gives a variable a buffer-local value associated with the current buffer; any time a different buffer is current, that variable will not be buffer-local. So, for example, if a closure foo has a private buffer (which is probably anonymous, but we'll call it foo_private_buffer) that it uses to store a bunch of state, and if it gives that buffer a buffer-local value for $Bar::Baz, then whenever any sub from package Bar is operating while foo_private_buffer is current it'll see foo's value of Baz. However, if foo calls a sub from package Twiddle, which uses a package-scoped buffer from package Twiddle, and if the the sub from Twiddle also calls a sub from Bar, _that_ sub will be working with (and changing, if applicable) the default (package-scoped) value of Baz.

However, elisp also has a mechanism (called make-variable-buffer-local) whereby a variable has a default value, but a normal attempt to change the value of the variable automatically makes it buffer-local to the current buffer, leaving the default unchanged. (The default can still be changed explicitely, however.) This semantic seems less useful to me, and I may not bother to implement it, though it would be easily enough added in if someone felt the need for it.


for(unpack("C*",'GGGG?GGGG?O__\?WccW?{GCw?Wcc{?Wcc~?Wcc{?~cc' .'W?')){$j=$_-63;++$a;for$p(0..7){$h[$p][$a]=$j%2;$j/=2}}for$ p(0..7){for$a(1..45){$_=($h[$p-1][$a])?'#':' ';print}print$/}

In reply to Re: Implementing (elisp-like) buffers in Perl 6: how to do buffer-localisation of arbitrary package variables? by jonadab
in thread Implementing (elisp-like) buffers in Perl 6: how to do buffer-localisation of arbitrary package variables? by jonadab

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-18 00:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found