Reiterador IV
Bem, prometi que disponibilizaria um artigo melhor sobre o assunto então está aí:
O Walter estava revisando, mas se alguém encontrar algum erro, por favor não culpe ele! Porque ele não teve tempo de me entregar o texto revisado.
[]'s
Como um hipopótamo lida com um campo de flores.
Bem, prometi que disponibilizaria um artigo melhor sobre o assunto então está aí:
Postado por ℭacilhας, ℒa ℬatalema às 12:37 PM
Tópicos: Programação, Tecnologia
Hoje vou reclamar... já está chegando em meu limite e minha sanidade está querendo tirar férias. =P
Estou trabalhando num projeto para uma organização não-governamental e já estou sem recebem desde novembro. Por culpa da organização? Não! Absolutamente!
A tal organização só faz pagamento por depósito em conta bancária. Bem, minha empresa se encontra atualmente sem conta bancária.
Fácil de resolver, não? Fui ao banco e iniciei o processo de abertura. Aí vem a primeira dor-de-cabeça...
Um de meus sócios, amarelão, disse que não vai assinar nada porque ele quer sair da firma e esta é uma forma de forçar sua saída.
Tudo bem... há saída...
Procurei meu contador e iniciei o processo para alteração contratual. Novo problema: meu outro sócio foi viajar!
Não posso fazer a alteração até ele voltar.
P. da vida com esta situação, ontem me liga uma cliente de um ISP onde presto serviço dizendo que o técnico deles tinha trocado a máquina principal da rede deles e que eles não conseguiam mais acessar a Internet. Como eu não estava lá na hora, o pessoal tentou resolver da melhor forma possível. O técnico da cliente disse que deixou toda rede configurada e pronta para acessar a Internet, e que não funcionava por culpa do ISP.
Chegando lá hoje pela manhã, desassociei o IP da cliente do endereço MAC, liguei para ela e disse que, como houve troca da máquina, o técnico dela deveria ter fornecido um novo endereço físico para funcionar. Como o pessoal do suporte também não havia pedido, eu fui lá na cliente para ajeitar a bagunça.
Chegando na cliente, ela estava com o técnico dela no telefone e disse que ele falou para ela que não existe endereço físico. Na mesma hora falei que ele só diria isso se não entendesse nada de Informática e peguei o telefone.
O técnico muito nervoso reclamou porque eu não deveria ter dito para ela que ele não entende nada e que ele havia trabalhado por quinze anos na IBM.
Perguntei para ele porque então ele falou para ela que não existe endereço físico e ele desconversou, dando a entender que ela entendeu mal o que ele disse. Depois falou que não funcionava por culpa do ISP e pediu para falar com a cliente de novo, com quem ficou reclamando um tempão.
Tudo bem. Respirei fundo, ignorei a abobrinha – a cliente pode ter entendido mal mesmo – e fui ver por que as máquinas não navegavam, e descobri um monte de coisas:
Postado por ℭacilhας, ℒa ℬatalema às 2:25 PM
Tópicos: Pessoal, Tecnologia
Passei quase o mês todo conversando com o Walter sobre closures, porque o ele está escrevendo um artigo muito bom sobre o assunto e eu estou revisando.
Como fiquei empolgado, resolvi escrever meu próprio artigo sobre o assunto, apenas como uma prévia para o artigo do Walter – muito melhor.
O conceito de closures (literamente «tampas», ou «clausuras») não é tão complicado assim, mas é preciso entender bem outros conceitos antes de chegar lá.
{
) e termina com fecha-chaves (}
), ou seja, todo e qualquer bloco de código é um escopo em si.sub mkfib {
my $a, $b = 0, 1;
return sub {
$a, $b = $b, $a+$b;
return $a;
};
};
my $fib = mkfib();
$fib->()
será retornado o próximo elemento da sequência. Em Perl, a palavra reservada my
indica que aquela(s) variável(is) pertence(m) ao escopo atual (local). Se não for usado my
, a variável será procurada no escopo pai e, se não existir, no anterior, até chegar ao global. Se a variável não existir no escopo global, será criada (no escopo global).def mkfib():
c = [0, 1]
def f():
c[0], c[1] = c[1], sum(c)
return c[0]
return f
fib = mkfib()
fib = (function ()
local a, b = 0, 1
return function ()
a, b = b, a+b
return a
end
end)()
local
equivale a my
de Perl).sub mkcounter {
my $c = 0;
return sub {
return ++$c;
};
};
$count = mkcounter();
def mkcounter():
c = [0]
def f():
c[0] += 1
return c[0]
return f
count = mkcounter()
count = (function ()
local c = 0
return function ()
c = c + 1
return c
end
end)()
Postado por ℭacilhας, ℒa ℬatalema às 10:30 PM
Tópicos: Programação, Tecnologia
Não é costume meu «reblogar», mas há coisas que valem a pena.
Vou fazer o seguinte, em vez de colocar o vídeo aqui, acho mais justo colocar um link pra página onde vi o vídeo:
Nação Livre – Bom de viola...
A técnica usada pelo violonista é conhecida como hammer-on (martelada). Isso sim é tocar violão!
[]'s
Postado por ℭacilhας, ℒa ℬatalema às 9:42 PM
Tópicos: Educação, Pessoal, Reblogging
Outro dia quando respondi um comentário do Tiago ao artigo PHP estúpido, estava muito zangado com alguns assuntos e o pobre Tiago acabou levando a bronca sem culpa no cartório.
Mas de qualquer forma, tirando o tom agressivo a resposta foi muito boa e esclarecedora, segundo o Silvio, quase um artigo.
Já escrevi um artigo sobre o assunto, mas nunca é demais reiterar.
Como há um senso comum na Informática de que passado é passado, o que deixa os mais novos (geralmente programadores com menos de 10 anos de computação) sem um background muito sólido, e os leva a acreditar em «verdades absolutas» cantadas por grandes empresas e defensores ferrenhos desta ou daquela ferramenta.
Tipagem estática não é a mesma coisa que tipagem forte! Uma linguagem pode ter tipagem fraca e estática, fraca e dinâmica, forte e estática, forte e dinâmica ou qualquer coisa intermediária.
Postado por ℭacilhας, ℒa ℬatalema às 8:49 PM
Tópicos: Programação, Tecnologia
É gente...
Quase sempre que converso com alguém sobre sistemas sócio-político-econômicos sou duramente criticado pro meus pontos de vista alternativos.
Vejam bem, antes de me rotular saibam que não sou comunista... por pouco. Acho as idéias de Karl Marx muito legais, mas um tanto utópicas.
Esclarecido o ponto, volto ao assunto principal: isto é Capitalismo.
Empresas transnacionais compraram dos governos terras «sem dono», colocando na estrada incontáveis indígenas e caboclos, e continuam a fazê-lo. Quem tem dinheiro pode...
Um grande defensor da soberania nacional e da Identidade Latino-americana foi assassinado na Bolívia pela CIA.
Isso para citar apenas grandes eventos passados... vamos chegar ao presente...
As pessoas são respeitadas por seus «contatos», ou seja, pela soma de dinheiro que pode ser gasta pelo conjunto de contatos de cada pessoa. Conhecimento, boa vontade, inteligência, nada disso tem importância (ou é hierarquicamente inferior ao capital potencial).
Não é meu objetivo final, mas quero passar pelo fato de uma modelo que cometeu atentado ao pudor em outro país consiga apoio legal no Brasil para criminosamente bloquear o acesso dos internautas brasileiros a um sítio internacional de hospedagem vídeos, que tanto contém besteiras quando vídeos úteis para estudo e trabalho, privando diversas pessoas, que não cometeram atentado ao pudor, de seu direito de acesso à informação.
Ou seja, uma única pessoa que foi pega em flagrante delito tem poder «legal» para prejudicar muitos e muitos brasileiros em pleno gozo de seus direitos. Isto é Capitalismo.
Vocês gostam do Capitalismo? Apoiam esta merda? Então aguentem! É assim que funciona.
Em outra oportunidade completarei meu raciocício, chegando à conclusão que realmente quero – agora não dá, não estou com cabeça pra tanto.
[]'s
PS.: Referências:
Aqueles que simplesmente não entendem (Ricardo Bánffy)
Sobre liberdade e justiça (Falcon_Dark)
Youtube bloqueado: Telefônica e Embratel avisam que vão seguir os passos da Brasil Telecom (Tatiana T – BR-Linux.org)
Às vezes sinto que nós brasileiros somos alienados da América Latina.
Somos rodeados por países de língua espanhola, mas aprendemos o inglês como língua estrangeira, o que nos afasta de nossa verdadeira identidade cultura.
Fica então algo em que se pensar:
O sentimento de unidade latino-americana é o limiar de um novo tempo. O esforço de organização para eliminar a opressão dos poderosos e construir um destino maior e mais justo é o compromisso solene de todos nós.
(Orestes Quercia)
Andei pensando e concluí que, como o primeiro artigo já foi voltado para programadores, o segundo deveria ter sido um pouco mais explicativo.
next()
), ele avança para o primeiro registro e retorna seus campos. Quando é requerido novamente, ele avança para o próximo registro, retornando-o, e assim sucessivamente até o último.Por questão de simplicidade passeremos a usar os seguintes termos:
- instância: uma tabela relacionada a uma metatabela (apesar de não ser o termo mais adequado);
- método: um par chave-valor onde o valor é uma função;
- atributo: qualquer outro par chave-valor de uma instância ou metatabela.
__index
da metatabela é chamada quando é feita uma tentativa de leitura de uma chave que a instância não possui.__index
da metatabela for uma tabela, a chave requerida é consultada nessa tabela. Por exemplo:t = { a = 2 }
setmetatable(t, { __index = { x = 0, y = 3 } })
t.x
retornará 0, pois o valor vem da tabela em __index
.t = { a = 2 }
setmetatable(t, {
__index = function (t, k)
return "-- chave " .. k .. " --"
end
} )
t.x
retornará a string «-- chave x --
».__newindex
da metatabela é chamada quando é feita uma tentativa de gravação em uma chave que a instância não possui. Seu valor é uma função cujos argumentos recebem a instância, a chave e o valor.iter
. Podemos usar a própria metatabela para armazenar as chaves.__index
.next()
.local iter = {}
iter.__index = iter
iter.__newindex = function (t, k, v)
-- Esta função apenas evita a criação de novas chaves
error("Chave " .. k .. " não existe")
end
self
é a classe e o primeiro argumento será a instância. Um construtor padrão em Lua é:function iter:new(o)
o = o or {}
setmetatable(o, self)
return o
end
iter
é local (digamos, privada), o construtor também será. Precisaremos de um construtor público... é nessa função que começaremos a mexer com corrotina.yield
).coroutine.create()
recebe uma função como parâmetro e retorna uma corrotina.O tipo retornado para uma corrotina (funçãotype()
) éthread
.
coroutine.resume()
, a função da corrotina é executada até encontrar uma chamada a coroutine.yield()
. Então coroutine.resume()
retorna true
e o parâmetro de coroutine.yield()
.coroutine.resume()
a função da corrotina continua até encontrar novamente coroutine.yield()
.iter
:function new()
local t = {}
t.co = coroutine.create(function ()
local a, b = 0, 1
while true do
a, b = b, a+b
coroutine.yield(a)
end
end)
return iter:new(t)
end
coroutine.resume()
a função correrá até o coroutine.yield()
, que retornará o próximo elemento.next()
, que tratará toda essa brincadeira e retornará um valor limpo:function iter:next()
local _, r = coroutine.resume(self.co)
return r
end
coroutine.resume()
retorna como primeiro valor true
para indicar que tudo correu bem, e como segundo o elemento que queremos. Então isolamos o retorno (na variável r
) e retornamos só o que interessa.local coroutine = coroutine
local error = error
local setmetatable = setmetatable
module "fib"
local coroutine = coroutine
local error = error
local setmetatable = setmetatable
module "fib"
local iter = {}
iter.__index = iter
iter.__newindex = function (t, k, v)
-- Esta função apenas evita a criação de novas chaves
error("Chave " .. k .. " não existe")
end
function iter:new(o)
o = o or {}
setmetatable(o, self)
return o
end
function iter:next()
local _, r = coroutine.resume(self.co)
return r
end
function new()
local t = {}
t.co = coroutine.create(function ()
local a, b = 0, 1
while true do
a, b = b, a+b
coroutine.yield(a)
end
end)
return iter:new(t)
end
fib.lua
), depois levante o interpretador e veja funcionando:lua> require "fib"
lua> f = fib.new()
lua> for i = 1, 10 do print(f:next()) end
1
1
2
3
5
8
13
21
34
55
Postado por ℭacilhας, ℒa ℬatalema às 9:33 AM
Tópicos: Programação, Tecnologia
Versão «metatabela + corrotina» do artigo anterior:
local coroutine = coroutine
local math = math
local setmetatable = setmetatable
local table = table
local type = type
module "rand"
-- Criação da metatabela
local iter = { sec = {} }
iter.__index = iter
iter.__newindex = function (t, k, v)
error("Chave " .. k .. " não encontrada")
end
-- Construtor local
function iter:new(o)
o = o or {}
setmetatable(o, self)
return o
end
-- Método principal
function iter:next()
local _, r = coroutine.resume(self.co)
return r
end
-- Construtor público
function new(t)
-- É preciso receber um vetor
if type(t) ~= "table" then
error "Parâmetro deve ser um vetor"
end
-- Vetor vazio?
if table.getn(t) == 0 then
error "Vetor vazio"
end
-- Criação da corrotina
t.co = coroutine.create(function (t)
-- Inicialição
local m, e
coroutine.yield(nil)
-- Loop principal
while true do
m = table.getn(t)
-- Se o vetor estiver vazio, começa de novo
if m == 0 then
while table.getn(t.sec) > 0 do
table.insert(t, table.remove(t.sec, 1))
end
m = table.getn(t)
end
-- Seleciona um elemento aleatoriamente
e = table.remove(t, math.random(m))
table.insert(t.sec, e)
coroutine.yield(e)
end
end)
-- Passa a tabela principal para a corrotina
coroutine.resume(t.co, t)
return iter:new(t)
end
Postado por ℭacilhας, ℒa ℬatalema às 8:21 PM
Tópicos: Programação, Tecnologia
Uma coisa fácil de fazer em Python é um reiterador (para quem gosta de estrangeirismos: «iterador», de iterator). Basta um simples comando yield
e está tudo resolvido.
Estava pensando comigo mesmo: e em Lua?
Então resolvi fazer um objeto que retorne indefinidamente e de forma aleatória os elementos de um vetor, mas sem repetir até que todos tenham sido retornados. Em Python a gente resolve isso com uma função:
from random import choice
def rand_new(*args):
assert len(args) > 0
t1 = list(args)
t2 = []
while True:
e = choice(t1)
t1.remove(e)
t2.append(e)
if len(t1) == 0:
t1, t2 = t2, []
yield e
local iter = { sec = {} }
iter.__index = iter
iter.__newindex = function (t, k, v)
error("Chave " .. k .. " não encontrada")
end
sec
vai funcionar como a lista t2
do código Python. A o próprio objeto (a parte indexada) vai funcionar como a lista t1
.function iter:new(o)
o = o or {}
setmetatable(o, self)
return o
end
function new(t)
if type(t) ~= "table" then
error "Esta função recebe um vetor como parâmetro"
end
if table.getn(t) == 0 then
error "Vetor vazio"
end
return iter:new(t)
end
function iter:reinit()
while table.getn(self.sec) > 0 do
table.insert(self, table.remove(self.sec, 1))
end
end
next()
(como no reiterador de Python):function iter:next()
local m, resp
m = table.getn(self)
-- Esvaziou? Recomeça do princípio...
if m == 0 then
self:reinit()
m = table.getn(self)
end
resp = table.remove(self, math.random(m))
table.insert(self.sec, resp)
return resp
end
local error = error
local math = math
local table = table
local setmetatable = setmetatable
local type = type
module "rand"
new()
em local e no final do arquivo declare a seguinte tabela:rand = { new = new }
lua> require "rand"
lua> a = rand.new { 1, 2, 3 }
lua> =a:next()
3
lua> =a:next()
1
lua> =a:next()
2
lua> =a:next()
2
lua> =a:next()
1
lua> =a:next()
3
lua> =a:next()
1
Postado por ℭacilhας, ℒa ℬatalema às 5:15 PM
Tópicos: Programação, Tecnologia
Começamos um novo ano com aquele mesmo gás anual, que sabemos terminará até o Carnaval no máximo, mas ainda assim gostaria de traçar alguns planos:
Vou continuar em 2007 a divulgação da língua internacional, em prol das culturas que estão sendo devastadas pela globalização.
Também vou continuar incentivando o uso da linguagem Lua, um bem cultural nacional, que os programadores brasileiros, se fossem um pouco mais perceptivos política e culturalmente, estaria usando e divulgando. Ainda também a linguagem de programação Python, uma das mais poderosas que já conheci.
Outra coisa que devo continuar é a incentivar o Software Livre, por motivos filosóficos sim, digam o que disserem os trasgos que só enxergam o lucro.
Convido também todos os que têm um pouco de consciência a fazer o mesmo – ou algo similar.
Que tal a campanha da sopa?
Que tal colaborar para com iniciativas de caridade, como a LBV?
Que tal simplesmente fazer o que é certo quando é tão fácil e tentador fazer o contrário?
Lugar comum? Baboseira altruísta? Talvez... mas que tal tentar?
Já pensaram: e se der certo?
Reblogging
, que pertencem a outros autores, sob suas próprias licenças.