Skip to content
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

dj.hook implementation #1

Open
ryanve opened this issue Jan 10, 2013 · 4 comments
Open

dj.hook implementation #1

ryanve opened this issue Jan 10, 2013 · 4 comments

Comments

@ryanve
Copy link
Owner

ryanve commented Jan 10, 2013

One of dj's most powerful methods is dj.hook(). Its mission is military-grade extensibility. It is designed to be:

  • safe - meaning that its design makes it hard for one bad line to break a whole app. It provides a safe access point for otherwise decoupled functionality.
  • adaptable - meaning that it can be applied to many situations, and that its capabilities are reusable. It can store functions that hook into points of other functions and/or can be used to store/access entire modules.
  • logical - meaning that it is systematic. It follows simple rules based on typeof checks. Thus it aims to be very reliable and learnable.

Over the last few months I've been developing the syntax/features and I'd like to get opinions on them now so that we can make any needed changes sooner rather than later. dj.hook() stores hooks in a private hash object. Its syntax is loosely analogous to jQuery's data methods.

Keys (identifiers) must be typeof "string" or "number". Each key represents a single value (not a stack). When you set a value it overrides the previous value. Each hook's first value is retained privately such that it is possible to restore default hooks.

Values (hooks) are restricted to being either typeof "function" or "object" and not null. Objects can be upgraded to functions, but not vice versa. This makes it so that if a hook is initiated as a function, then it will remain so. For safety, values cannot easily be deleted.

Version 0.7.0 implementation:

// basic usage
dj.hook( key )        // get a hook value
dj.hook( key, value ) // set a hook value (function or object)

// heavy lifting
dj.hook() // get all (get a clone of the hash at its current state)
dj.hook( undefined ) // same as dj.hook()
dj.hook( object ) // set multiple hooks via an object's key/value pairs
dj.hook( object, prefix ) // like above + prefix is added to each key
dj.hook( callback ) // same as dj.hook( callback.call(this, dj.hook()) )
dj.hook.remix() // return a new hook method tied to a fresh hash

// ops
dj.hook( key, false ) // lock a hook at its current state
dj.hook( false )      // lock all hooks at their current state
dj.hook( key, true )  // restore a hook's default value
dj.hook( true )       // restore all default hooks

// detects
dj.hook( key, null )  // get status (true => writable, false => locked)
dj.hook( null )  // get status (true => all writable, false => all locked)

It might be slightly more expressive to have separate submethods for the "ops" or "detects", but it seems safer and much terser to have them all wrapped in one function. Having them all within ensures that the operations are done on the intended hash. Typechecking is necessary regardless so it is rather efficient under the hood. (See source.)

The purpose of this thread is to help make sure that the syntax is intuitive/expressive enough and that the right features are there. Opinions?

@ryanve
Copy link
Owner Author

ryanve commented Jan 10, 2013

Are the "detects" even necessary? Would the null syntax be better applied to accessing default values?

// alternate idea
dj.hook( key, null )  // get the default hook represented by key
dj.hook( null )  // get a clone of the "defaults" hash object

@ryanve
Copy link
Owner Author

ryanve commented Jan 10, 2013

I'm planning on adding the ability to call a callback each time a hook value is updated, such that you could listen to a hook that is uninitiated and then do something if/when it is. This would add asynchronous possibilities and could also be used to trigger custom events. I'd like to implement this with a syntax analogous to jQuery's on/off methods:

// planned future features
dj.hook.on( callback ) // call callback each time the hash is changed
dj.hook.on( key, callback ) // call callback each time key's hook is changed
dj.hook.off( callback ) // remove callback previously added via dj.hook.on
dj.hook.off( key, callback ) // remove callback previously added via dj.hook.on

@alanhogan
Copy link

Feel free to ignore this comment, but taking a only quick look at dj and dj.hook, and reading this thread, I’m not sure of the intended use cases of dj.hook.

@alanhogan
Copy link

Actually, I think I get it, given your comment in ryanve/response.js#18.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants