Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import inspect, ast
- from forbiddenfruit import curse
- def get_from_outer_scope(name):
- idx = 1
- while True:
- try:
- return inspect.stack()[idx][0].f_locals[name]
- except KeyError:
- idx += 1
- class dot_func:
- def __init__(self, func):
- self.func = func
- def __getattr__(self, name):
- var_name, *attr_names = name.split('ˈ')
- val = get_from_outer_scope(var_name)
- for attr in attr_names:
- val = getattr(val, attr)
- self.func(val)
- puts = dot_func(print)
- class MutableString:
- def __init__(self, string):
- self._string = string
- def __str__(self):
- return self._string
- def __repr__(self):
- return f'MutableString({self._string!r})'
- def __setitem__(self, key, value):
- if isinstance(key, int):
- self._string = self._string[:key] + value + self._string[key+1:]
- if isinstance(key, str):
- self._string = self._string.replace(key, value)
- def __getattr__(self, name):
- if name == 'upcase':
- return self._string.upper()
- return self.__getattribute__(name)
- def _times_impl(count):
- curframe = inspect.currentframe()
- calframe = inspect.getouterframes(curframe, 1)
- call_str = repr(calframe[2][4])[2:-4]
- expr = ''
- lvl = 1
- for char in reversed(call_str[:-1]):
- if char == ')':
- lvl += 1
- if char == '(':
- lvl -= 1
- if lvl == 0:
- break
- expr = char + expr
- for _ in range(count-1):
- eval(expr)
- curse(str, 'm',lambda self: MutableString(self))
- curse(int, 'times', lambda self, expr: _times_impl(self))
- '''
- The code I'm trying to copy:
- # Output "I love Ruby"
- say = "I love Ruby"
- puts say
- # Output "I *LOVE* RUBY"
- say['love'] = "*love*"
- puts say.upcase
- # Output "I *love* Ruby"
- # five times
- 5.times { puts say }
- '''
- # Output "I love Python"
- say = "I love Python".m()
- puts.say
- # ^ I didn't find a way to modify str.__setitem__ (didn't work with forbiddenfruit)
- # so i made a different class that is returned by str.m()
- # Output "I *LOVE* PYTHON"
- say['love'] = "*love*"
- puts.sayˈupcase
- # ^ the puts method replaces ˈ with . when evaluating.
- # This is done because python evaluates __getattr__ from left to right
- # Output "I *love* Python"
- # five times
- (5).times(puts.say)
- # ^ I didn't find a way to cancel the evaluation of puts.say
- # when times is called, times evaluates the expression n-1 times.
- # therefore (0).times(something) unfortunately evaluates something once.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement