Pull to refresh
73
0
Артур Хашаев @Invizory

User

Send message
У Марка Симана есть хорошая заметка насчет монады Maybe в .NET. Соль в том, что можно ничего не подключать и не реализовывать, ведь она у вас давно уже есть, вы просто раньше ее не замечали.

Пример кода
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Ploeh.Samples.Booking.DomainModel
{
    public class Maybe<T> : IEnumerable<T>
    {
        private readonly IEnumerable<T> values;

        public Maybe()
        {
            this.values = new T[0];
        }

        public Maybe(T value)
        {
            this.values = new[] { value };
        }

        public IEnumerator<T> GetEnumerator()
        {
            return this.values.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }

    public static class Maybe
    {
        public static Maybe<T> ToMaybe<T>(this T value)
        {
            return new Maybe<T>(value);
        }

        public static Maybe<T> Empty<T>()
        {
            return new Maybe<T>();
        }
    }
}
Говоря о конфигурации веб-приложения, мы, как правило, имеем в виду все, что может отличаться для нескольких экземпляров одного и того же приложения, запущенного в разных окружениях. Скажем, параметры доступа к БД, очередям сообщений, внешним сервисам (API-ключи, логины-пароли) — это все конфигурация, тогда как список роутов или описание подключаемых компонентов в IoC-контейнере ею не являются — это уже внутренний конфиг, фактически, часть кода. Отсюда сразу следует рекомендация строго разделять конфигурацию и код — конфиг может меняться в разных окружениях, тогда как код для всех един.

Поэтому, как правило, разработчики используют конфигурационные файлы. Некоторые все еще продолжают их класть в репозиторий, а остальные этого уже не делают и заполняют конфиги для каждого деплоя. Еще одна часто распространенная практика — написать пару-тройку готовых конфигов для основных окружений и положить их в репозиторий — в качестве примера можно привести известное заклинание «development, test, production». Понятно, однако, что такой способ не очень-то масштабируется.

Соответственно, также используется и тот подход, о котором мы говорим — хранить конфигурацию в переменных окружения. Вот его достоинства:

  • Переменные окружения легко менять, к тому же для разработчиков есть такие штуки как Foreman и autoenv.
  • Не получится случайно закоммитить конфиг от околобоевого окружения в репозиторий, в отличие от файлов-конфигов.
  • Это, фактически, единственный способ описать конфигурацию, который не зависит от ОС, используемой платформы или языка.

Как можно понять, это все неплохо вписывается в приложения, которым нужен высокий уровень гибкости и масштабируемости, а также подходит для новомодных облачных моделей типа PaaS и IaaS — одними переменными окружения мы можем рулить чем и кем угодно, вне зависимости от платформы — можно хоть на чистом C код писать. Именно поэтому такие сервисы, как, например, Heroku, используют переменные окружения для конфигурирования.
Некоторые советы в этой книге Боба Мартина довольно спорные, на самом деле. Вот хороший критический отзыв на нее, там в том числе и этот пример с PrimeGenerator бегло проанализирован.
Хотелось бы еще добавить к комментарию выше, что Foreman в первую очередь — инструмент разработчика, а не администратора. Более того, он поддерживает экспорт в том числе и в supervisord.
Да, конечно можно, например:

$ foreman export upstart /etc/init -c habr=4 -c web=2
Попробуйте cygwin/msys + mintty. Получите привычное окружение и неплохой эмулятор терминала.
Зашел, чтобы увидеть здесь богиню
image
Ждем статью от автора со срывом покровов про АОП?
Кстати, у того же mono есть C# REPL, довольно удобно.

$ csharp
Mono C# Shell, type "help;" for help
 
Enter statements below.
csharp> using System.IO;
csharp> from f in Directory.GetFiles("/etc")
      >   let fi = new FileInfo(f)  
      >   where fi.LastWriteTime > DateTime.Now - TimeSpan.FromDays(7) select f; 
{ "/etc/adjtime", "/etc/asound.state", "/etc/mtab", "/etc/printcap", "/etc/resolv.conf" }
csharp>
Самое приличное, что я видел для питона — это verb-based парсер Argh. По сути, все что нужно сделать — взять готовые функции и навесить декораторов.
Не обязательно писать полные пути до файлов. Можно в конфиге RequireJS указать пути:
requirejs.config({
       <...>
	paths: {
		jquery: 'third-party/jquery.min',
		underscore: 'third-party/underscore.min',
		backbone: 'third-party/backbone.min',
                <...>
	},
});
И если даже что-то изменится, то достаточно будет поменять путь к файлу в загрузчике.
Нда, к сожалению, в комментариях этот финт не работает, но в постах можно писать как-то так:

<table>
	<tr>
		<td>
			<source lang="python">
1
2
			</source>
		</td>
		<td>
			<source lang="python">
def hello(name):
    print("Hello, " + name)
			</source>
		</td>
	</tr>
</table>
Спасибо за статью.
Хотелось бы также отметить, что построение этого самого отсортированного списка циклических перестановок можно написать более эффективнее, чем алгоритмом «в лоб». Для этого используется такая структура данных, как суффиксный массив и его можно построить за линейное время.
Судя по этому документу нужно пройти идентификацию, а потом получить пин-код по телефону.
<...> вы сможете снимать деньги и в банкоматах. Комиссия при этом составит 3% от суммы + 15 рублей (но не менее 100 рублей).
Хабрахабр, очевидно :)
Нда, промазал. Комментарий предназначался для комментатора чуть выше.
ООО Единая Россия

Знаете ли, у Единой России ответственность совсем не ограниченная :)
1

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity