Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #352 (closed enhancement: fixed)

Opened 13 years ago

Last modified 12 years ago

RuleDispatch usage should provide a parameter that is under user control

Reported by: kevin Owned by: anonymous
Priority: normal Milestone: 0.9
Component: TurboGears Version:
Severity: normal Keywords:
Cc:

Description

Right now, RuleDispatch? is used for things like jsonify and sqlwidgets. Phillip Eby's recommended way to allow users to override the default rules that come with TurboGears is to provide a way for users to pass in some kind of information and then include that in their rule. This works because RuleDispatch? picks the most specific rule.

Change History

comment:1 Changed 13 years ago by Simon Belak <simon.belak@…>

Not very elegant, but it works:

In util.py or some such let's define:

tg_override = object()

One can than write:

@foo.when("tg_override and y!=0")
def bar(x,y):
  return x/y

Since object instances are compared by id this approach even works in such ridicules cases as:

@foo.when("object() and y!=0")
def evil_bar(x,y):
  return x/y

@foo.when("tg_override and object() and y!=0")
def good_bar(x,y):
  return x/y

comment:2 Changed 13 years ago by Simon Belak <simon.belak@…>

In cases where the user intends to simply change behaviour for a certain set of rules, around() could be used instead of primary methods. Assuming default implementation does not use around(), of curse. But than again, if it does, full (re)implementation is probably not the way to go in the first place.

comment:3 Changed 13 years ago by Simon Belak <simon.belak@…>

P.S. I am aware that what is proposed above is not in the spirit of generic functions, but it does simplify matters for those who consider generic functions to abstract and/or difficult to fully comprehend. Especially if we would provide a more meaningful alias for around().

comment:4 Changed 13 years ago by simon

Another idiom would be to use two generic function. The first would be exposed to end users and have only default specialisation where it would call the second GF with all framework-level specialisations implemented.

comment:5 Changed 13 years ago by simon

  • Status changed from new to closed
  • Resolution set to fixed

Added a more or less definitive solution in [1066].

Any generic function we want to be trivially overridden should be derived from turbogears.genericfunctions.MultiorderGenericFunction?:

@generic(MultiorderGenericFunction)
def foo(a, b):
  pass

introducing (optional, default being 0) argument order:

@foo.when("a > 10", order=2)
def a_gt_10(a, b):
  pass

What this does is alter method combination so that methods are first ordered into groups according to order argument and only then within every group by relation "more specific".

In other words:

p.order < r.order => p is more specific than r for every pair of rules p, r.

Note: See TracTickets for help on using tickets.