OT: Re: Just took a look in the perl newsgroup....

Carl Banks imbosol at aerojockey.com
Fri May 30 17:24:17 EDT 2003


Cliff Wells wrote:
> On Thu, 2003-05-29 at 10:40, Carl Banks wrote:
>> 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'
> 
> This thread has been most intriguing.  I doubt I would ever use this
> stuff in 'real' code, but still, fun to play with.  Here's my version of
> the above:
> 
> class _switch:
>    def __call__(self, v):
>        class Case(Exception): value = v
>        self._value = Case
>        raise self._value
> 
>    def case(self, v):
>        if not hasattr(self, '_value'):
>            raise # raise "real" exceptions in user code
> 
>        if self._value.value == v:
>            return self._value
>        return v
>    
>    def default(self):
>         return self._value
>    
> switch = _switch()
> case = switch.case
> default = switch.default
> 
> for v in range(1,6):
>    print v,
>    try: switch(v)
>    except case(1):
>        print 1
>    except case(2):
>        print 2
>    except case(4):
>        print 4
>    except case(v):
>        print "one way to spell default"
>    # except default():
>    #    print "another way to spell default"
> 
> 
> This has a couple of advantages:
> 1.  Doesn't stomp all exceptions, i.e. switch(x) in the above code would
> still raise NameError (although there might be a better way of doing
> this, I just got tired of tinkering with it).
> 2.  Doesn't have a global cache.
> 3.  Doesn't require 'raise switch()' which I found unacceptable <wink>

All good points.  Ok, here's the nested scopes version:

    def create_switch_functions():
        cache = {}
        class BaseCaseException(Exception):
            pass
        def switch(v):
            if cache.has_key(v):
                raise cache[v]
            else:
                class CaseException(BaseClassException):
                    pass
                cache[v] = CaseException
		raise CaseException
        def case(v):
            if cache.has_key(v):
                return cache[v]
            else:
                class CaseException(BaseClassException):
                    pass
                cache[v] = CaseException
                return CaseException
        default = BaseClassException
        return switch, case, default


One enhancement is the use of a BaseClassException to catch defaults.
Used same as above, except default isn't a function to be called.


-- 
CARL BANKS




More information about the Python-list mailing list