terça-feira, abril 30, 2013

Monkey patch em Python

Monkey patch, o patch do macaco! Não explica muita coisa, não é? Na comunidade Python é uma expressão bastante comum. Para entender seu significado, vejamos o seguinte exemplo.

Considere que temos uma classe Robot escrita no módulo (arquivo python) chamado agents.py.

código original (agents.py):

class Robot(object):
    def __init__(self):
        self.position = 0

    def ahead(self):
        self.position += 1
 

    def other_method(self):
        print "Other method"


       
O monkey patch consiste em susbstituir atributos, métodos, funções e até classes de outro módulo em tempo de execução. No nosso exemplo, poderíamos fazer um monkey patch do método ahead() da classe Robot da seguinte maneira:

código (patch.py):

import agents

def monkey_ahead(self_like_parameter):

    print "MONKEY PATCH"
    self_like_parameter.position += 3

if __name__ == "__main__":
    agents.Robot.ahead = monkey_ahead
    my_robot = agents.Robot()
    my_robot.ahead()
    print my_robot.position
    my_robot.other_method()


Execute python patch.py e terá o seguinte resultado:

$ python patch.py
MONKEY PATCH
3
Other method


O (monkey) patch foi realizado na linha agents.Robot.ahead = monkey_ahead. Aqui a função monkey_ahead fez se passar pelo método ahead da classe Robot existente no módulo agents.

Isso é possível devido à tipagem dinâmica do Python (também conhecida como "duck typing").

Pelos resultados obtidos, verifica-se também que outros métodos (como other_method) e atributos (como position) continuam acessíveis e funcionando.

Podemos dizer então que o monkey patch é um enxerto no código. É um remendo! E claramente é algo que deve ser evitado ou, no mínimo, usado com extremo cuidado.

Fica bastante claro que o uso de monkey patch é totalmente acoplado ao código original. E isso é ruim. Se for usar, saiba o que está fazendo.


Outras fontes para consulta:

http://www.mindfiresolutions.com/Monkey-Patching-in-Python-1238.php
http://stackoverflow.com/questions/5626193/what-is-monkey-patching

segunda-feira, abril 22, 2013

Thoughts about Plone and Zope


  • Programar pela ZMI Web é um modo reconhecidamente ultrapassado. (Program in ZMI is a recognizably outdated way.)
Em Zope 2 Book, relata:
"One of the most notable differences between the original Zope2 approach and todays best-practices is in the way you develop applications with Zope2. The original Zope2 approach has focussed on a Through-The-Web (TTW) development model. You would create your entire application and manage your data through the same browser interface and store everything transparently in the same database. This model has worked very well in the beginning of “the web” as many dynamic websites have been rather simple and specialized projects.
Over the years websites have grown their requirements and often turned into development projects of a considerable size. Today websites are understood as applications in themselves and need an approach which is no longer compatible with the TTW approach of the early Zope2."
  • Conceito de aquisição do Zope 2 (Concept of Acquisition)
"One more prominent aspect of Zope is acquisition, whose core concepts are simply that:
  • Zope objects are contained inside other objects (such as Folders).
  • Objects can "acquire" attributes and behavior from their containers."
Diferença entre herança e aquisição: "Inheritance stipulates that an object can learn about its behavior from its superclasses via an inheritance hierarchy. Acquisition, on the other hand, stipulates that an object can additionally learn about its behavior through its containment hierarchy. In Zope, an object’s inheritance hierarchy is always searched for behavior before its acquisition hierarchy. If the method or attribute is not found in the object’s inheritance hierarchy, then the acquisition hierarchy is searched."
"Acquisition is not limited to searching a containment hierarchy: it can also search a context hierarchy. Acquisition by context is terribly difficult to explain, and you should avoid it if at all possible."
"Acquisition allows behavior to be distributed hierarchically throughout the system."
"Acquisition is a mechanism in Zope for sharing information among objects contained in a folder and its subfolders."
  • Separar camada de apresentação e de lógica (Keep presentation and logic separate)
"Zope encourages you to keep your presentation and logic separate by providing different objects that are intended to be used expressly for “presentation”. “Presentation” is defined as the task of dynamically defining layout of web pages and other user-visible data. Presentation objects typically render HTML (and sometimes XML)." (fonte
  • Prefira ZPT à DTML (ZPT is better than DTML)
Motivo 1: DTML é velho. "an older version of a presentation facility included, which is called Document Template Markup Language or short DTML."
Motivo 2: DTML não faz boa separação entre camada de apresentação e camada responsável pela lógica: "There is a major problem with many languages designed for the purpose of creating dynamic HTML content: they don’t allow for “separation of presentation and logic” very well. For example, “tag-based” scripting languages, like DTML, SSI, PHP, and JSP, encourage programmers to embed special tags into HTML that are, at best, mysterious to graphics designers who “just want to make the page look good” and don’t know (or want to know!) a lot about creating an application around the HTML that they generate. Worse, these tags can sometimes cause the HTML on which the designer has been working to become “invalid” HTML, unrecognizable by any of his or her tools."
  • Contribuições do CMF ao Zope 2 original (Contribs of CMF inside Zope2)
"Zope ships with several content components: ZSQL Methods, Files, and Images. You can use Files for textual content since you can edit the contents of Files if the file is less than 64K and contains text. However, the File object is fairly basic and may not provide all of the features or metadata that you need.
Zope’s Content Management Framework (CMF) solves this problem by providing an assortment of rich content components. The CMF is Zope’s content management add on. It introduces all kinds of enhancements including workflow, skins and content objects. The CMF makes a lot of use of Page Templates."

Hibernate e erro Oracle ORA-00942: table or view does not exist

Ao se deparar com um erro do tipo ORA-00942 (a tabela ou view não existe), veja algumas situações que podem estar produzindo o erro:


  • A tabela pode realmente não existir.
  • Seu mapeamento pode estar errado (especialmente se por motivos de força maior você usa arquivos .hbm.xml para configuração)
  • Você esqueceu de incluir as classes mapeadas (resources) no hibernate.cfg.xml
  • O usuário que você utilizou pode não ter privilégios (grants) na tabela
  • O Hibernate pode estar se perdendo em alguma tabela sinônima (crie um sinônimo com o comando SQL "CREATE PUBLIC SYNOMYN".

Anotação: CompositePattern em Python

Python possui interfaces implícitas: no exemplo abaixo a interface é definida pela existência de um método "matches" nos objetos participantes do Composite.

class CompositePattern:
    def __init__(self):
        self.patterns = []
    
    def add(self, pattern):
        self.patterns.append(pattern)
    
    def matches(self, date):
        for pattern in patterns:
            if not pattern.matches(date):
                return False
        return True

cp = CompositePattern()
cp.add(YearPattern(2004))
cp.add(MonthPattern(9))
cp.add(DayPattern(29))

Fonte: