OT: Re: Just took a look in the perl newsgroup....
Carl Banks
imbosol at aerojockey.com
Thu May 29 13:40:13 EDT 2003
Bengt Richter wrote:
> On Wed, 28 May 2003 14:17:37 -0600, Steven Taschuk <staschuk at telusplanet.net> wrote:
>
>>Quoth Bengt Richter:
>> [...]
>>> IMO that's still a workaround for the case (;-) where you want to rebind
>>> in the same scope. But I just thought of an alternative, which see below
>>> in stripped-down version of previous example:
>> [...]
>>> ## a local case structure with rebinding in local scope
>>> try: raise `x`
>>> except '1':
>>> # case code in same scope as case
>>> inner_var = '<<value bound in scope of "case" 1)>>'
>>> except '2':
>>> inner_var = '<<value bound in scope of "case" 2>>'
>>> except:
>>> inner_var = '<<value bound in scope of "case" default>>'
>>
>>Yikes.
>>
>>Inherently fragile due to reliance on interning of repr(x). Won't
>>work at all if/when string exceptions go away.
> Which version requires interning of repr(x)? It looks like the code is less
> efficient than the corresponding if/elif/else code, however.
>
>>
>>A strong candidate for a Most Outlandish Proposal award. (In
>>fact, I think you're a strong candidate for a Lifetime Achievement
>>Award in this area. <0.25 wink>)
>>
> LOL ;-)
> I figure the best QA for toys is playing with them ;-)
>
> Responding to the objections above <~ ^ @>
>
> ====< ycase.py >=====================================
> class Switch(object):
> def __init__(self, *caseNames):
> for name in caseNames:
> if not isinstance(name,str): name = `name`
> exec ('class _%s(Exception):pass'%name) in self.__dict__
> del self.__dict__['__builtins__']
> def __call__(self, name):
> raise getattr(self, '_%s'%name, ValueError)
>
> case = switch = Switch(1,2,'foo')
>
> def f(x):
> def g(x):
> inner_var = 5
> ## a local case structure with rebinding in local scope
> try: switch(x)
> except case._1:
> # case code in same scope as case
> inner_var = '<<value bound in scope of "case" 1)>>'
> except case._2:
> inner_var = '<<value bound in scope of "case" 2>>'
> except case._foo:
> inner_var = '<<value bound in scope of "case" foo>>'
> except:
> inner_var = '<<value bound in scope of "case" default>>'
> print 'inner_var as seen at end of "case":', inner_var
> g(x)
>
> for i in (0,1,2,'foo'): print '---- f(%r) -----'%i; f(i)
> =====================================================
> [19:59] C:\pywk\clp>ycase.py
> ---- f(0) -----
> inner_var as seen at end of "case": <<value bound in scope of "case" default>>
> ---- f(1) -----
> inner_var as seen at end of "case": <<value bound in scope of "case" 1)>>
> ---- f(2) -----
> inner_var as seen at end of "case": <<value bound in scope of "case" 2>>
> ---- f('foo') -----
> inner_var as seen at end of "case": <<value bound in scope of "case" foo>>
>
> ;-)
>
> Regards,
> Bengt Richter
Better, perhaps, have the "case" cache results, like this:
_case_cache = {}
def case(v):
if _case_cache.has_key(v):
return _case_cache[v]
class Case(Exception):
value = v
_case_cache[v] = Case
return Case
switch = case
Then the resulting case statement looks like:
try: raise switch(n)
except case(1):
print 1
except case(2):
print 2
except:
print 'default'
Very neat, clever idea.
--
CARL BANKS
More information about the Python-list
mailing list