Arquivo do mês: novembro 2012

Diários de Bicicleta I

Hoje resolvi colocar em execução o projeto de ir de bicicleta ao trabalho. Fui numa Dahon Boardwalk S1 (sem marchas e com freio contrapedal) igual a da imagem acima. Abaixo uma imagem do trajeto.

Comecei a registrar em Ipanema mas saí mesmo do Leblon.

Abaixo estão os dados do trajeto:

Como no trabalho não tem bicicletário coloquei a bicicleta numa bolsa e usei um carrinho de malas para levá-la até debaixo do meu bureau.

Pretendia voltar de Metrô. Saí cerca de 18:00 e como estava claro resolvi voltar todo o trajeto de bicicleta. Os dados sobre a volta estão abaixo:

Curioso sobre se havia algum outro post ou artigo com o mesmo título deste post encontrei o livro  Diários de Bicicleta: http://pt.wikipedia.org/wiki/Di%C3%A1rios_de_Bicicleta.

Anúncios

Expensify

Create expenses from receipt images

Put all of your plane tickets, hotel invoices, car reservations and other receipts in to the Expensify folder. We will sync with it automatically and SmartScan the merchant, date and amount from each receipt image to create an expense entry. So easy, you may forget how to type.

Keep track of your expense reports

A new export option allows you to send your approved reports to theExpensify folder inside Evernote. Fully searchable PDF expense reports are now at your fingertips!

https://www.expensify.com/evernote

Apache Thrift

The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

http://thrift.apache.org/

Links relacionados:

Lisp and Smalltalk are dead: It’s C all the way down

Gabriel contrasts two design philosophies, the MIT/Stanford philosophy (which he calls “the right thing“) and the “New Jersey” C/UNIX philosophy (which he calls “worse is better”).  In short form, the MIT/Stanford philosophy (which he associates with Lisp, and which I also associate with Smalltalk) is that correctness and consistency are the most important design quality. In Lisp and Smalltalk, we have S-expressions and objects consistently.  The C/UNIX philosophy places simplicity in interface and implementation as the most important design quality.

http://computinged.wordpress.com/2009/08/14/lisp-and-smalltalk-are-dead-its-c-all-the-way-down/

Method Wrapper in Pharo/Smalltalk

rotate-zoom-out-withdraw

O pacote MyMethodWrappers contém vários comandos (classes) para criação de method wrapper. Usam a técnica New Selector, citada em Wrappers to the Rescue, de forma aproximada. Podemos criar wrappers em torno de um único método, uma lista de métodos ou todos os métodos de uma classe. Também é possível instrumentar todos os métodos de todas as classes de um pacote. A seguir vamos exemplificar com algum código mostrando como usar os comandos. A remoção dos wrappers também é facilitada. Serão implementados wrappers genéricos, tracers, inspectors, assertions. Usaremos pragmas (Veja links no final) em alguns casos.

Vamos exibir um trace das ativações dos métodos. O método #calculate acima não está instrumentado ainda e será o primeiro a ser chamado para iniciar o encadeamento de mensagens através de objetos das classes ClientOfRomanCalculator, MyRomanCalculator e MyRomanConverter.

Os métodos que serão rastreados são mostrados abaixo:

O método acima será chamado na criação do objeto da classe ClientOfRomanCalculator. Nele é criado o objeto da classe MyRomanCalculator, o que faz com que o método abaixo seja invocado.

O método initialize é invocado na criação de cada objeto na imagem do Pharo conforme pode ser visto no método abaixo:

O método new não será rastreado por estar em outro pacote que não o MyMethodWrappers-Sandbox que será especificado quando formos instalar os wrappers.

Finalmente o initialize abaixo de MyRomanConverter é invocado.

A sequência de inicializações será disparada pela invocação abaixo:

Depois do método #new o método #calculate (abaixo) é chamado.

Como é mostrado no método acima a sequência seguinte de chamadas invoca os métodos #firstNumber:, #secondNumber: e #add da classe MyRomanCalculator, mostrados a seguir.

O método #add acima, por sua vez, invoca os métodos #toDecimal (duas vezes) e #toRoman da classe MyRomanConversor, mostrados abaixo:

Os métodos acima foram implementados como se a classe MyRomanConverter fosse um mock, normalmente usados em testes de unidade (já que não queríamos desenvolver os conversores).

O file-out com o código segue abaixo:

Object subclass: #ClientOfRomanCalculator
	instanceVariableNames: 'calculator'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'MyMethodWrappers-Sandbox'!

!ClientOfRomanCalculator methodsFor: 'updating' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
calculate
	| result |
	result := calculator
		firstNumber: 'V';
		secondNumber: 'XIV';
		add.
	^ result! !

!ClientOfRomanCalculator methodsFor: 'initialize-release' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
initialize
	super initialize .
	calculator := MyRomanCalculator new! !

!ClientOfRomanCalculator methodsFor: 'testing' stamp: 'FranciscoAryMartins 11/14/2012 21:15'!
name
	^ 'client'! !

Object subclass: #MyRomanCalculator
	instanceVariableNames: 'firstNumber secondNumber converter'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'MyMethodWrappers-Sandbox'!

!MyRomanCalculator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
add
	^ converter toRoman: (converter toDecimal: firstNumber) + (converter toDecimal: secondNumber)! !

!MyRomanCalculator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
firstNumber: aByteString
	firstNumber:= aByteString! !

!MyRomanCalculator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
initialize
	super initialize .
	converter := MyRomanConverter new! !

!MyRomanCalculator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 21:15'!
name
	^ 'calculator'! !

!MyRomanCalculator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
secondNumber: aByteString
	secondNumber:= aByteString ! !

Object subclass: #MyRomanConverter
	instanceVariableNames: 'firstTime'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'MyMethodWrappers-Sandbox'!

!MyRomanConverter methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
initialize
	super initialize .
	firstTime := true! !

!MyRomanConverter methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 21:15'!
name
	^ 'converter'! !

!MyRomanConverter methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
toDecimal: aByteString
	"mock"
	firstTime ifTrue: [firstTime := false. ^ 5] ifFalse: [^ 14]! !

!MyRomanConverter methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/14/2012 23:19'!
toRoman: aSmallInteger
	^ 'XIX' "mock"! !

O diagrama de sequência abaixo descreve o panorama dinâmico.


Vamos instalar os wrappers em todo um pacote executando o código abaixo. O objetivo é obter um tracer mostrando alguns dados relativos à ativação dos métodos ilustrando o potencial dos wrappers.

Todos os métodos de todas as classes do pacote serão instrumentados com exceção dos métodos #name que são usados no wrapper e que, se instrumentados, gerariam uma recursão infinita. A técnica de usar block closures permite injetar variáveis locais no wrapper. Abaixo mostramos um dos métodos instrumentados.

O box em vermelho mostra a chamada ao método original.

O resultado da execução é a listagem abaixo:


Unwrapping #balance:...
Unwrapping #balance...
Unwrapping #withDraw:...
Unwrapping #deposit:...
Unwrapping #initialize...
Unwrapping #removeAccount:...
Unwrapping #addAccount:...
Unwrapping #calculate...
Unwrapping #initialize...
Unwrapping #firstNumber:...
Unwrapping #add...
Unwrapping #initialize...
Unwrapping #secondNumber:...
Unwrapping #toRoman:...
Unwrapping #initialize...
Unwrapping #toDecimal:...
Wrapping #balance:...
Wrapping #balance...
Wrapping #withDraw:...
Wrapping #deposit:...
Wrapping #initialize...
Wrapping #removeAccount:...
Wrapping #addAccount:...
Wrapping #calculate...
Wrapping #initialize...
Wrapping #firstNumber:...
Wrapping #add...
Wrapping #initialize...
Wrapping #secondNumber:...
Wrapping #toRoman:...
Wrapping #initialize...
Wrapping #toDecimal:...
------------------------------------------------------------------
sender: an instance of Behavior inside method #new
message: #initialize
arguments #()
receiver: an instance of ClientOfRomanCalculator
------------------------------------------------------------------
sender: an instance of Behavior inside method #new
message: #initialize
arguments #()
receiver: an instance of MyRomanCalculator
------------------------------------------------------------------
sender: an instance of Behavior inside method #new
message: #initialize
arguments #()
receiver: an instance of MyRomanConverter
###### result from initialize ==> a MyRomanConverter
###### result from initialize ==> a MyRomanCalculator
###### result from initialize ==> a ClientOfRomanCalculator
------------------------------------------------------------------
sender: an instance of UndefinedObject inside method #DoIt
message: #calculate
arguments #()
receiver: an instance of ClientOfRomanCalculator
------------------------------------------------------------------
sender: an instance of ClientOfRomanCalculator inside method #calculate
message: #firstNumber:
arguments #('V')
receiver: an instance of MyRomanCalculator
###### result from firstNumber: ==> a MyRomanCalculator
------------------------------------------------------------------
sender: an instance of ClientOfRomanCalculator inside method #calculate
message: #secondNumber:
arguments #('XIV')
receiver: an instance of MyRomanCalculator
###### result from secondNumber: ==> a MyRomanCalculator
------------------------------------------------------------------
sender: an instance of ClientOfRomanCalculator inside method #calculate
message: #add
arguments #()
receiver: an instance of MyRomanCalculator
------------------------------------------------------------------
sender: an instance of MyRomanCalculator inside method #add
message: #toDecimal:
arguments #('V')
receiver: an instance of MyRomanConverter
###### result from toDecimal: ==> 5
------------------------------------------------------------------
sender: an instance of MyRomanCalculator inside method #add
message: #toDecimal:
arguments #('XIV')
receiver: an instance of MyRomanConverter
###### result from toDecimal: ==> 14
------------------------------------------------------------------
sender: an instance of MyRomanCalculator inside method #add
message: #toRoman:
arguments #(19)
receiver: an instance of MyRomanConverter
###### result from toRoman: ==> XIX
###### result from add ==> XIX
###### result from calculate ==> XIX

Para desfazer (unwrap) a geração dos method wrappers execute o código abaixo:


Durante o desenvolvimento dos wrappers pode-se optar por invocar #unwrap antes do #wrap para garantir que todas as instrumentações feitas sejam removidas durante uma seção de debugging.

No método MyMethodWrapper>>#wrapSourceString reside o código que gera o wrapper:

Nota: Os métodos #wrap e #unwrap são idempotentes.

Para instrumentar um único método execute um código similar ao abaixo:

Para instrumentar uma lista de métodos use algo similar a:

Alternativamente pode-se usar #includings:

Para instrumentar todos os métodos basta não especificar uma lista de métodos:

No próximo post vamos implementar um tracer e assertions. Usaremos também pragmas como alternativa para manter as informações sobre como gerar os wrappers junto aos métodos. Isto facilitará a manutenção do código pelo programador.

Links sobre pragma:

Pink Gin na enseada de Botafogo

 

Fonte: http://www.marinetraffic.com/ais/default.aspx?level0=100

MockFlow

 

MockFlow is an Online Design Suite providing design tools and collaboration services for designers. Its flagship software – “MockFlow Wireframe” is used by thousands of customers worldwide.

Fonte: http://www.mockflow.com/

Links relacionados: