В trunk появилась новая долгожданная фича: Scalar type hints
Выглядит это приблизительно так:
< ?php
function doSomething( int $foo){
echo "{$foo}\n";
}
?>
Если в такую функцию передать не целое – получим Catchable fatal error
В trunk появилась новая долгожданная фича: Scalar type hints
Выглядит это приблизительно так:
< ?php
function doSomething( int $foo){
echo "{$foo}\n";
}
?>
Если в такую функцию передать не целое – получим Catchable fatal error
Меркуриал в последнее время стал моей основной системой контроля версий, и естественно у меня появился некоторый опыт, которым по моему мнению пора бы и поделиться.
Начнем с небольшого сравнения со старым добрым Subversion.
Долго пытаясь вспомнить недостатки децентрализованных система контроля версий нашел только один: возможность фальсификации авторства коммита — для проектов в которых я участвую такая фальсификация не несет никому никакого вреда, а потому я не считаю это большим недостатком.
Чуть позже при написании статьи вспомнил еще один, уже достаточно серьёзный недостаток — невозможность забрать часть репозитория. В любой современной децентрализованной системе контроля версий репозиторий является единой сущностью, а потому стянуть на машину разработчика только часть репозитория, как в Subversion и CVS не выйдет. Однако проблема с разделением репозитория решается именно его РАЗДЕЛЕНИЕМ.
Теперь попытаюсь вспомнить преимущества.
Локальный игнор-файл — файл содержащий паттерны для исключения файлов/каталогов из-под контроля версий может контроллироваться системой, а может быть так же исключен из-под контроля. Последний вариант дает разработчикам огромные возможности для хранения внутри рабочей копии дополнительных файлов, таких, как например инструменты разработчика, sql-дампы, да все, что только можно придумать. Простейший пример: Одни разработчики используют Eclipse, другие Netbeans, третьи Komodo, а каждая из этих сред создает в корне проекта файлы с мета-информацией о проекте. Включать эти файлы и папки в контроль версий смысла нет, а добавлять все возможные варианты в игнор, грозит его разрастанием.
Автоматический бэкап. Это преимущество неоспоримо, ведь каждый из разработчиков имеет на своей машине самодостаточный репозиторий, который можно в любой момент сделать главным (ну если вдруг сервер упал… с пятого этажа).
Получается, что главным преимуществом распределенных систем контроля версий является именно их распределенность. Преимущества этой распределенности распознаются разработчиками далеко не сразу, а только тогда, когда приходит некоторый опыт использования DVCS, потому я сейчас попробую обяснить удобства этой самой распределенности на примерах.
Для начала немного теории! Помните централизованные системы контроля версий? Там есть единый репозиторий в который мы коммитим и с которого обновляем нашу рабочую копию. В распределенных системах репозиторий находится прямо внутри рабочей копии. В Меркуриал репозиторий хранится в каталоге .hg прямо в корне проекта (рабочей копии). Все фиксации изменений и обновления происходят локально. Казалось бы все как и в централизованной системе, однако при надо же как-то делиться изменениями с другими разработчиками? Вот тут и начинается та самая распределенность. Чтобы опубликовать (протолкнуть в терминологии Mercurial) наши изменения в общий репозиторий (вспоминаем? система распределенная – репозиториев много) мы должны их сначала зафиксировать локально (commit), и только потом отправить в обший репозиторий (push). Для того, чтобы получить чужие изменения в свой локальный репозиторий (втягивать в терминологии Mercurial) мы должны выполнить комманду pull (тянуть). Когда чужие изменения уже находятся в нашем репозитории мы можем иметь 2 ветки изменений – 1) ветка наших изменений с несколькими коммитами 2) ветка чужих изменений тоже с несколькими коммитами. Ветки в итоге сходятся к одному родительскому узлу (changeset или «набор изменений» в терминолонии Меркуриал)
…… продолжение следует…
В математике функция отображает объекты из одного множества (множества определения функции) в другое (множество значений функции). Математические функции (их называют чистыми) “механически”, однозначно вычисляют результат по заданным аргументам. Чистые функции не должны хранить в себе какие-либо данные между двумя вызовами. Их можно представлять себе черными ящиками, о которых известно только то, что они делают, но совсем не важно, как.
В соответствии с модульным подходом к программированию большая задача разбивается на несколько более мелких, каждую из которых (в идеале) решает отдельный модуль. В разных методологиях даются различные ограничения на размер модулей, однако при построении модульной структуры программы важнее составить такую композицию модулей, которая позволила бы свести к минимуму связи между ними. Набор классов и функций, имеющий множество связей между своими элементами, было бы логично расположить в одном модуле. Есть и еще одно полезное замечание: модули должно быть легче использовать, чем написать заново. Это значит, что модуль должен иметь удобный интерфейс: набор функций, классов и констант, который он предлагает своим пользователям.
Today I’m trying to use Python again and write small twitter-updater for command line interface
You must have a config file $HOME/.twitter.ini for use this script
[auth]
user = twit_user
password = ******
Usage:
./twit.py your message
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, urllib, httplib2, os, ConfigParser
def tweet(msg):
post = urllib.urlencode({ 'status' : msg })
http = httplib2.Http()
http.force_exception_to_status_code = False
user,passwd = getConfig()
http.add_credentials(user,passwd)
resp, content = http.request('http://twitter.com/statuses/update.xml', 'POST', post)
if resp and resp.status == 200:
print "Ok!"
else:
print "Error: ",resp.status
print content
print "============================================="
def getConfig():
filename = os.path.expanduser('~/.twitter.ini')
config = ConfigParser.RawConfigParser()
config.read(filename)
try:
return config.get('auth','user'), config.get('auth','password')
except:
print "Please check configuration file: ",filename
print "Folowing file format required: "
print "+---------------------------+"
print "| [auth] |"
print "| user=twitter_username |"
print "| password=***** |"
print "+---------------------------+"
sys.exit(1)
sys.argv.reverse()
sys.argv.pop()
sys.argv.reverse()
message = " ".join(sys.argv)
tweet(message)


