From: Sam H. <sh...@ma...> - 2005-10-17 18:18:28
|
Hi Guys, I often find I'd like to use values from the course environment from places other than content generator classes (where they're available via $self->r->ce). For example, the date parsing functions in Utils.pm need the timezone, the database record classes could benefit from having access to default values, and so on. The current solution seems to be to either pass the entire $ce object into the function in question, or grab only the needed values from $ce and pass those in. It's somewhat of a hassle in the common case, and a big hassle in some cases. Examples: * I'd like to add methods to the DB record classes to return human- readable versions of database values. To format date strings, I need a timezone. So a simple call like $GlobalSet->pretty_print; becomes $GlobalSet->pretty_print($timezone); * This is also the reason why I put the new status mangling functions in CourseEnvironment itself instead of in a database class. From CourseEnvironment.pm: > There is a set of operations that require certain data from the course > environment. Most of these are un Utils.pm. I've been forced to > pass $ce into > them, so that they can get their data out. But some things are so > intrinsically > linked to the course environment that they might as well be methods > in this > class. * The Utils::CourseManagement functions need $ce values. * Classes like HTML::ScrollingRecordList and Utils::SortRecords/ FormatRecords could benefit from having access to settings in $ce -- one could customize the display of lists, add new sort methods and format strings, etc. * I also just noticed the parseDateTime and formatDateTime wrappers in ContentGenerator.pm that serve to work around this problem by grabbing the timezone from $ce and passing it to the real functions in Utils.pm. I'm considering making $ce a dynamically scoped variable with a line like local $CE = $ce; in WeBWorK.pm. This would make $CE available from any code called by WeBWorK.pm. It would make global.conf function much more like Global.pm did in the WW1 days -- you could access it from anywhere, and rely on its presence. The main objection I see is that it would make it harder to pull pieces of WW code out and use them in places where a course environment is not available. However, the current practice of passing $ce in to many functions has the same effect. Furthermore, CourseEnvironment.pm itself is failry portable. We use it in several command-line scripts without inconvenience. I'm tempted to make the entire WeBWorK::Request object dynamically scoped -- that would give us access to $ce, $db, $authz, etc. from anywhere. However, this would be much worse in terms of modularity, since we'd also have access to $r->param() from anywhere, and I fear that the temptation to check and modify params from places that should be request-independent would be too great and would lead to spaghetti code. I don't take a change like this lightly, and I'd like your input on possible problems with this approach as well as alternate solutions. -sam |