<![CDATA[]]> http://hes.yvision.kz/feed/ Fri, 17 Nov 2017 23:34:48 +0600 https://yvision.kz/images/userpics/hes-normal.jpghttp://hes.yvision.kz all rights reserved Zend_Feed Мантра любвиhttps://www.youtube.com/watch?v=u9jlEvPi06k

Ом шанти, шанти ом!

Из уважения к моим братьям.

]]>
Sat, 07 Jan 2017 03:34:59 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/720183https://yvision.kz/post/720183
Архив номеров журнала «Квант».По ссылке -

http://kvant.mccme.ru/index.htm

 

Интересно будет полистать.

]]>
Sun, 16 Oct 2016 17:35:02 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/664787https://yvision.kz/post/664787
Функциональное программирование. Golang

Немного предыстории.

Go был рожден из-за неудовлетворенности от существующих языков и сред системного программирования. Программирование стало слишком сложным, и нынешние языки в этом частично виноваты. Приходится выбирать между эффективной компиляцией, эффективным выполнением и легкостью программирования — все три качества недоступны в одном и том же мэйнстримовом языке. Программисты выбирали легкость программирования вместо безопасности и эффективности, переходя на динамически типизированные языки, такие как Python и JavaScript, вместо C++ или, в меньшей степени, Java.

Go — попытка соединить легкость программирования на интерпретируемом, динамически типизированном языке с эффективностью и безопасностью статически типизированного, компилируемого языка. Он так же стремится быть современным, поддерживая сетевые и многоядерные вычисления. Наконец, Go задумывался как быстрый язык: компиляция большого выполняемого файла должна занимать не более нескольких секунд. Чтобы реализовать эти цели, нужна выразительная, но легкая система типов, конкарентность и сборка мусора, твердая спецификация зависимостей и т.д. Эти вещи не могут быть хорошо реализованы в библиотеках, нужен был новый язык.

Какова цель проекта?

За последнее десятилетие не появилось ни одного значительного системного языка программирования, но за это время компьютерная сфера сильно изменилась. Несколько трендов:

  • Компьютеры стали намного быстрее, а разработка ПО быстрей не стала.
  • Управление зависимостями стало большой частью разработки программ, а традиционные Си-подобные "заголовочные файлы" несовместимы с чистым анализом зависимостей и быстрой компиляцией.
  • Начинается бунт против громоздких языков вроде Java и C++, из-за чего люди переходят на динамически типизированные языки типа Python и JavaScript.
  • Некоторые фундаментальные концепции, такие как сборка мусора и параллельное вычисление, плохо поддерживаются популярными системными языками программирования.
  • Появление многоядерных компьютеров вызвало беспокойство и замешательство.

Корпорация Google считает, что стоит попробовать сделать новый язык, конкарентный, со сборкой мусора и быстрой компиляцией. Насчет пунктов выше:

  • Большие программы Go компилирует за несколько секунда на одном компьютере (и это действительно так, 63 Мб исходного кода компилируются на домашнем компьютере ровно 7 секунд, причем одинаково компилируется как на Windows машине, так и на Linux и Mac).
  • Go предоставляет такую модель создания программ, при которой избегаются издержки Си-подобных заголовочных файлов и библиотек, делая анализ зависимостей простым.
  • Система типов Go не имеет иерархии, поэтому не тратится время на определение зависимостей между типами. Кроме того, хотя типизация в Go статическая, язык пытается сделать так, чтобы программисты не чувствовали их громоздкость, как в типичных объектно-ориентированных языках.
  • Go имеет полноценную сборку мусора, а так же предоставляет фундаментальную поддержку конкарентного выполнения и коммуникаций.
  • В язык заложен способ создания системного ПО для многоядерных компьютеров.

Насчёт простоты кода.

Абстрактный код в вакууме представляет собой реализацию протокола Qiwi для провайдера услуг. Читается вообще без каких либо проблем. После изучения Go буквально за 1-2 дня этот код написан за 2-3 часа после работы в пятницу(!).

Интересные материалы и видео

Go success stories from around the web

Введение в программирование на Go

HighLoad++ 2012. Язык программирования Go от Google

Интерактивное изучение Golang

Интервью: Брайан Керниган и Алан Донован

Русскоязычные подкасты на iTunes

Погружение в Google Go

Видеозапись докладов конференции Golang Moscow (Digital October) (докладчики из компаний Яндекс, Openstat (Spylog), sports.ru)

Доклад Антона Поварова "Go в Badoo" на Golang Meetup

Сайт о языке программировани Go

Роб Пайк подверг критике C++ и Java

Centrifuge + Go = Centrifugo – harder, better, faster, stronger

Why is Golang popular in China?

]]>
Tue, 01 Dec 2015 13:44:30 +0600Hes@yvision.kz (Hes)go golang googlehttps://yvision.kz/post/634129https://yvision.kz/post/634129
Функциональное программирование. Параллельное программирование. TPL DataFlowПоговорим немного о TPL Dataflow.

Эта библиотека, позволяющая повысить производительность и устойчивость параллельных приложений.

Для .Net Framework 4.0 и 4.5 библиотека поставляется посредством NuGet.

Подход, используемый в TPL Dataflow, состоит в следующем:

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

В TPL Dataflow используется парадигма программирования потоков данных: Вики

В TPL DataFlow существуют 3 основных вида блоков:

  • Блоки источники - источники данных, из которых можно читать.
  • Блоки приёмкники - приёмники данных, в которых можно писать.
  • Блоки распространители - являются одновременно и источниками и приёмниками данных.

Блоки можно связывать, образуя вычислительные конвейеры. Один блок-источник можно связывать с множеством блоков-приёмников. Один блок-приёмник можно связывать с множеством блоков-источников. В методе связывания источника с целевым объектом LinkTo, можно указать делегат, который определяет, принимает или отклоняет целевой блок сообщение в зависимости от содержания этого сообщения. Механизм фильтрации позволяет гарантировать, что блок потока данных будет получать только определенные значения.

Существует 3 категории блоков: буферные, исполнительные, группирующие.

  • Блоки буферизации хранят данные для использования блоками потребителями данных.
  • Исполнительные блоки выполняют заданный делегат над каждым принятым сообщением.
  • Группирующие блоки объединяют данные от множества источников с разными ограничениями.

Практический пример.

Хороший пример можно найти тут, тут и тут.

]]>
Fri, 21 Aug 2015 11:24:38 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/531280https://yvision.kz/post/531280
Функциональное программирование. Параллельное программирование.Все, кто программирует на C#, так или иначе использовали оператор foreach.

Этот оператор используется как правило для итерации коллекции и применяет вложенные операторы к каждому элементу коллекции. Добавлять или удалять элементы коллекции при этом не рекомендуется, так как возможны побочные эффекты.

Но, что, если нам необходимы длительные вычисления над элементами последовательности и полученные результаты не зависят друг от друга?

В .NET Framework 4 появились интересные возможности параллельности: Parallel.ForEach и Parallel LINQ (PLINQ).

* В этой статье я не рассматриваю такие вещие как async-await  и другие вещи, касающиеся .NET Framework 4.5.

Простейший форма метода ForEach выгляди следующим образом:


  1. public static ParallelLoopResult ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body)
  2. {
  3. if (source == null)
  4. {
  5. throw new ArgumentNullException("source");
  6. }
  7. if (body == null)
  8. {
  9. throw new ArgumentNullException("body");
  10. }
  11. return ForEachWorker<TSource, object>(source, s_defaultParallelOptions, body, null, null, null, null, null, null);
  12. }
 

#mce_temp_url#

Этот метод разбивает данные на части и оперирует над элементами в различных потоках.

Метод возвращает сведения о состоянии цикла.

Пример абстрактного коня в вакууме (как всегда - из рабочего проекта):

 

  1. public void Start()
  2. {
  3. Parallel.ForEach(_components,
  4. component =>
  5. {
  6. Console.WriteLine("Component loaded: {0}", component.Value.Description);
  7. foreach (var value in component.Value.Execute())
  8. _storage.Save(XElement.Parse(value));
  9. });
  10. }
 

В этом коде происходит вызов множества компонент (каждая компонента - сборка .NET), каждый из которых загружает множество Xml документов, и сохраняет их в некое абстрактное хранилище.

При этом сохранение происходит асинхронно, то есть без задержек.


  1. async Task Save(XElement message);
]]>
Tue, 18 Aug 2015 14:08:20 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/504709https://yvision.kz/post/504709
Функциональное программирование. Язык программирования F#F# — это мультипарадигменный язык программирования, разработанный в подразделении Microsoft Research и предназначенный для исполнения на платформе Microsoft .NET. Он сочетает в себе выразительность функциональных языков, таких как OCaml и Haskell с возможностями и объектной моделью .NET.

Год назад F# в рейтинге Tiobe занимал 69 строчку в рейтинге популярности, сейчас же - 19 место. По прогнозам Tiobe, F# будет уверенно входить в 10 самых популярных языков в мире.

Забрать F# можно отсюда для Windows, отсюда для Linux, отсюда для Android и отсюда для Mac.

Все функциональные возможности F# реализованы в конечном итоге поверх общей системы типов .NET Framework. Однако этот факт не обеспечивает удобства использования таких конструкций из других языков платформы. При разработке собственных библиотек на F# следует предусмотреть создание объектно-ориентированных обёрток, которые будет проще использовать из C# или Visual Basic .NET.

С обучением и литературой, всё очень даже хорошо, к примеру проект Try F#, WikiBooks. Из книг: Tomas Petricek with Jon Skeet. Real-World Functional Programming. Часть книги есть на MSDN. Вторая книга: Tao Liu. F# for C# Developers. Обе эти книги очень хорошо подходят разработчикам, пишущим на C#. Есть еще очень интересная книга другого автора: Johan Astborg. F# for Quantitative Finance, к ней также прилагаются исходные коды на GitHub, что само по себе здорово.

Типичный хелловорлд:

 
  1. let message = "Hello world!"
  2. printfn "%s" message

Пример посложнее. Пусть стоит задача вычисления чётных чисел от 0 до 10:

 
  1. let numbers = [ 1 .. 10 ] // List в C#
  2. let isOdd(n) = (n%2 = 1) // Функция определения чётности
  3. let square(n) = n * n // Функция определения квадрата числа
  4. //Ищем квадрат чётного числа в списке
  5. let squared =
  6. numbers
  7. |> List.filter isOdd
  8. |> List.map square
  9. //
  10. val it : int list = [1; 9; 25; 49; 81]

List.filter - предложение where в Linq

List.map - предложение select в Linq

Императивный стиль в F#

 
  1. let mutable sum = 0
  2. for i in [0..100] do
  3. if i%2 <> 0 then sum <- sum + i
  4. printf "the sum of odd numbers from 0 to 100 is %d n" sum

Эти примеры лишь малая часть того, что представляет собой F#.

]]>
Thu, 11 Dec 2014 19:08:41 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/447952https://yvision.kz/post/447952
Функциональное программирование. Функциональное программирование — что это?Вчера сходил на IT Crowd. Открытая конференция разработчиков.

Было много интересного. Но вот, что удивило. Подавляющее большинство присутствующих разработчиков вообще не знает и даже не подозревает о функциональном программировании и даже, что оно так называется. Поэтому решил выложить честно стыренную страничку с хабра и даже прояснить некоторые моменты, которые нам демонстрировал Данияр.

Мне бы хотелось добавить больше научности и больше конкретики:)

Геттеры и сеттеры - для чего нужны и как на самом деле они называются?

В функциональном программировании широко используются неизменяемые структуры данных. Работа с ними значительно отличается по сравнению с изменяемыми данными.

В основе этого лежит тот факт, что при изменении какой-либо части неизменяемой структуры данных создается ее копия, отличающаяся от оригинала этой самой измененной частью. Полное копирование всей исходной структуры не эффективно, поэтому новая структура как правило использует ссылки на неизмененные части из оригинала.

В функциональном программировании широко используются неизменяемые структуры данных. Работа с ними значительно отличается по сравнению с изменяемыми данными.В основе этого лежит тот факт, что при изменении какой-либо части неизменяемой структуры данных создается ее копия, отличающаяся от оригинала этой самой измененной частью. Полное копирование всей исходной структуры не эффективно, поэтому новая структура как правило использует ссылки на неизмененные части из оригинала.

Для упрощения построения (компоновки) сетеров (и гетеров) неизменяемых структур данных удобно использовать инструмент линзы.


  1. class Lens<TObject, TProperty>
  2. {
  3. public Func<TObject, TProperty> Get {get; private set;}
  4. public Action<TObject, TProperty> Set {get; private set;}
  5.  
  6. public Lens(Func<TObject, TProperty> getter, Action<TObject, TProperty> setter)
  7. {
  8. Get = getter;
  9. Set = setter;
  10. }
  11. }

Пример использования:


  1. class Person
  2. {
  3. public string Name {get;set;}
  4. public int Age {get;set;}
  5. }
  6.  
  7. void Main()
  8. {
  9. // Линза для имени
  10. var name = new Lens<Person,string>(p => p.Name, (p, v) => p.Name = v);
  11.  
  12. // Линза для возраста
  13. var age = new Lens<Person,int>(p => p.Age, (p, v) => p.Age = v);
  14.  
  15. var person = new Person {Name = "Вася", Age = 30};
  16.  
  17. // Выведем имя и возраст
  18. name.Get(person).Dump(); // output: Вася
  19. age.Get(person).Dump(); // output: 30
  20.  
  21. // Установим при помощи линзы имя.
  22. name.Set(person, "Петя");
  23. name.Get(person).Dump(); // output: Петя
  24. }

Такой приём часто используется множеством различных ORM - данные напрямую менять нельзя, но при помощи линз - вспомогательных методов, запросто можно нарисовать обёртки для чтения-записи куда и откуда угодно. Побочных эффектов от ввода-вывода можно избежать, используя монаду IO.

Каррирование.

Материал из Википедии — свободной энциклопедии

Каррирование или карринг (англ. currying) в информатике — преобразование функции от многих аргументов в функцию, берущую свои аргументы по одному.


  1. Func<int, Func<int, int>> curry = (x => (y => x + y));
  2. var xx = curry(4)(5);
  3. Console.WriteLine(xx); //9
  4. var yy = curry(4);
  5. Console.WriteLine(yy(5)); //9

Применяться может где и как угодно - от парсеров, до расчёта финансовых транзакций (финансовые формулы писать функциями очень удобно).

Чистота функций.

Материал из Википедии — свободной энциклопедии

В функциональных языках программирования, чистая функция, это функция, которая:

является детерминированной;

не обладает побочными эффектами.

]]>
Sat, 01 Nov 2014 13:09:31 +0600Hes@yvision.kz (Hes)функциональноефункциональное программированиеc#https://yvision.kz/post/435697https://yvision.kz/post/435697
Web-разработка. Сервисы рассылки sms в Казахстане с точки зрения разработчика.Небольшой обзор.

Недавно мне потребовался стабильный и надёжный сервис для массовой рассылки sms-сообщений. Для этого, мне необходимо было провести анализ существующих операторов на рынке (буквально 2 страницы поиска в гугле). Задача была поставлена так:

Необходимо найти самый дешёвый и легко интегрируемый отечественный сервис. Под "легко интегрируемый" я подразумеваю, что компания, предоставляющая данный вид сервиса, предоставляет потенциальным пользователям примеры исходных кодов с подробными комментариями, а не выкидывает сервис без соответствующей документации - для программиста нет ничего хуже, чем разбирательства с чёрными ящиками. Так что наличие примеров и исходников на различных языках программирования непосредственно на сайте будет идти большим плюсом. Также наличие небольшого баланса на счету - для тестирования и закрепления результатов, внушает доверие к сервису. Также учитывается количество смс - от 1000 до 5000. Также, мне неважны "готовые решения", которые так активно продвигаются - меня интересует кастомное решение.

Дизайн мне неважен, важно насколько проработаны решения. Очерёдность обзора: хаотично:)

1. http://www.sms1.kz/

Стоимость 1 смс - 4 тенге. Интеграционный интерфейс отсутствует. Нецелесообразно.

2. http://kazinfoteh.kz/

Стоимость не указана. Интеграционный интерфейс вроде бы как присутствует, но по факту на сайте ничего нет. Нецелесообразно.

3. http://qmobo.kz/

Стоимость 1 смс  - 5 тенге. Интеграционный интерфейс вроде бы как присутствует, но по факту на сайте ничего нет. Нецелесообразно.

4. http://www.quicktelecom.kz/. Полезно лишь для Web-разработчиков, но для серьезных решений - неприменимо. Нецелесообразно.

5. http://sms2.proconnect.kz/. Даже не знаю, что сказать. При регистрации зачем-то просит номер сотового телефона. С интеграционным интерфейсом - беда. Нецелесообразно. Непонятно, зачем он вообще в 1 строчках гугла.

6. http://smspro.kz/. Первый из сервисов, который по-честному мне понравился. Правда стоимость 1 смс - 6 тенге для KCell, зато цена 1 смс для Beeline, Tele-2.- 4.8 тенге. Имеется вменяемая документация, на основе которой, можно построить интеграционный интерфейс. Указаны показатели качества сервиса, что должно невероятно радовать разработчика. Бесплатное тестирование.

7. http://smsc.kz/. Еще один из сервисов, который живёт на рынке достаточно давно. Тарификация достаточно гибкая, поэтому здесь ее описывать смысла нет.

8. http://sms-service.kz/. Возможно, самый дешевый сервис. Стоимость 1 смс - от 3.4 тенге. Документация имеется, но примеров с исходными кодами нет. В принципе не критично, но хотелось бы видеть набор не хуже чем у http://smsc.kz/. Терпимо.

9. http://unisender.kz/. Стоимость 1 смс - от 4.2 тенге. Документация, примеры исходных кодов имеются. Для .NET также имеется готовая библиотека, что очень даже хорошо.

10. http://www.epochtasms.kz/. Стоимость 1 смс - от 3.4 тенге. Еще один дешевый сервис. Документация, примеры исходных кодов, подробное описание ошибок - просто рай для разработчика. Что понравилось - консультант 24х7 в сети.

То, что не вошло в обзор:

1. http://unisms.kz/ (много букоф, мало смысла).

2. http://brandsms.kz/ (взорвался мозг, и от дизайна и от наполнения).

Итог.

Для меня выбор очевиден как никогда - http://www.epochtasms.kz/ является победителем безоговорочно.

Напомню, обзор сервисов был создан разработчиком и для разработчиков.

Дополнение: готовую библиотеку для работы со шлюзом выложу на блоге позже.

]]>
Fri, 24 Oct 2014 21:43:19 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/435628https://yvision.kz/post/435628
Функциональное программирование. Инверсия управления (TinyIoC)Как известно, инверсия управления, это важный принцип SOLID, позволяющий писать слабо связанный код, повышая в разы гибкость кода.

Существует множество IoC-контейнеров (NInject, Unity, AutoFac и другие).

Для начинающих есть хорошая статья здесь.

Я же, в своих проектах использую TinyIoC - небольшие размеры, и то, что его использует проект NancyFx (Уроки по фреймворку nancy, и объяснение, что это, можно найти тут).

Первая задача - нам нужно объявить контейнер и что-то в него положить.

Проект у меня простой и демонстрационный, поэтому статического контейнера мне вполне хватает.

 
  1. public static class AppContainer
  2. {
  3. private static TinyIoCContainer _instance;
  4. public static TinyIoCContainer Instance
  5. {
  6. get { return _instance ?? RegisterInstance(); }
  7. }
  8. private static TinyIoCContainer RegisterInstance()
  9. {
  10. var instance = new TinyIoCContainer();
  11. instance.Register<IYviEnumerable, YviEnumerable>();
  12. _instance = instance;
  13. return _instance;
  14. }
  15. }

В этом коде я в контейнере регистрирую некоторый интерфейс и реализацию, которая может поменяться в любой момент (достаточно написать класс, отнаследовавшись от IYviEnumerable и заменить ненужный нам класс).

Использование контейнера.

Типы, зарегистрированные в контейнере можно запросить напрямую из контейнера:

 
  1. var yviEnumerable = AppContainer.Instance.Resolve<IYviEnumerable>();

Либо инъекцией типа в конструктор любого класса.

На этом пока всё.

Небольшая поправка.

Что делать, если нам требуется зарегистрировать в контейнере несколько классов одного и того же интерфейса?

   
  1. instance.Register<IModule, StatisticLoader>("statistic");
  2. instance.Register<IModule, Storage>("storage");
  3. instance.Register<IModule, Http>("http");

Просто регистрируем:)

И резольвим список классов, зарегистрированных на один и тот же интерфейс:

   
  1. IEnumerable<IModule> modules = container.ResolveAll<IModule>();
]]>
Fri, 24 Oct 2014 16:09:01 +0600Hes@yvision.kz (Hes)https://yvision.kz/post/435569https://yvision.kz/post/435569
Web-разработка. Функциональный граббинг сложных сайтов (yvision.kz)На написание статьи меня натолкнула другая статья, пользователя @webПростой граббинг, сложных сайтов. C# (на примере Yvision.kz). В этой статье показано императивное решение задачи, я же задался вопросом - можно ли решить задачу, используя смешанные парадигмы, в частности функциональная (Linq) и императивная (ООП)?

Как оказалось - можно. Для этого я изначально поставил вопрос - что я хочу видеть в итоге? Есть сайт - Yvision, есть БД, куда надо будет сливать список статей, аналогично вышеуказанной статье, остается лишь мелочь - что же всё-таки мы будем сливать в БД?

Для этого был создан POCO-класс Yvision, который и будет характеризовать данные, которые мы хотим получить от сайта и которые мы будем записывать в БД.

   
  1. public class Yvision
  2. {
  3. /// <summary>
  4. /// Идентификатор статьи
  5. /// </summary>
  6. public string Id { get; set; }
  7. /// <summary>
  8. /// Наименование статьи
  9. /// </summary>
  10. public string Name { get; set; }
  11. /// <summary>
  12. /// Ссылка на статью
  13. /// </summary>
  14. public string Link { get; set; }
  15. /// <summary>
  16. /// Автор статьи
  17. /// </summary>
  18. public string Author { get; set; }
  19. /// <summary>
  20. /// Блог автора
  21. /// </summary>
  22. public string AuthorUrl { get; set; }
  23. /// <summary>
  24. /// Изображение статьи
  25. /// </summary>
  26. public string Image { get; set; }
  27. }

Дальше мне понадобился некий перечислитель, скрывающий методы работы с HtmlAgilityPack - так как программисту, пользующему библиотеку парсинга конкретно yvision.kz не всегда интересно знать как она устроена, главное, что она делает.

   
  1. public class YviEnumerable : IEnumerable<Yvision>
  2. {
  3. public YviEnumerable()
  4. {
  5. _yvisions = new HtmlWeb()
  6. .Load("http://www.yvision.kz")
  7. .DocumentNode
  8. //Выберем нужную нам ноду
  9. .SelectSingleNode("//div[@class="mainContent main_page"]")
  10. //Выберем все дивы ноды
  11. .Descendants("div")
  12. //Где класс - статья
  13. .Where(d => d.Attributes.Contains("class") && d.Attributes["class"].Value.Contains("home_article1 big"))
  14. //Непосредственно трансформация данных
  15. .Select(node => new Yvision
  16. {
  17. //Id дива с которого берем данные
  18. Id = node.Id,
  19. //Url новости
  20. Link = _queryNodes(node, "hold").Element("a").Attributes["href"].Value,
  21. //Изображение
  22. Image = _queryNodes(node, "hold").ChildNodes.Elements("img").First().Attributes["src"].Value,
  23. //Наименование
  24. Name = _queryNodes(node, "text1").ChildNodes.Elements("a").First().InnerText,
  25. //Автор
  26. Author = _queryNodes(node, "author").Element("a").InnerText.Trim(),
  27. //Блог автора
  28. AuthorUrl = _queryNodes(node, "author").Element("a").Attributes["href"].Value
  29. });
  30. }
  31. /// <summary>
  32. /// Коллекция новостей Yvision
  33. /// </summary>
  34. private readonly IEnumerable<Yvision> _yvisions;
  35. public IEnumerable<Yvision> Yvisions
  36. {
  37. get { return _yvisions; }
  38. }
  39. /// <summary>
  40. /// Функция выборки единичного элемента с заданным классом
  41. /// </summary>
  42. private readonly Func<HtmlNode, string, HtmlNode> _queryNodes = (p, s) => p
  43. .Descendants("div")
  44. .First(d => d.Attributes.Contains("class") && d.Attributes["class"].Value.Contains(s));
  45. /// <summary>
  46. /// Возвращает перечислитель коллекции новостей
  47. /// </summary>
  48. /// <returns></returns>
  49. public IEnumerator<Yvision> GetEnumerator()
  50. {
  51. return _yvisions.GetEnumerator();
  52. }
  53. IEnumerator IEnumerable.GetEnumerator()
  54. {
  55. return GetEnumerator();
  56. }
  57. }

Собственно на этом всё. Дальнейших танцев с бубнами особо не требуется - кое-где необходимо переписать стандартные функции на чистые (выбрасывать исключения нам не нужно) и даже местами можно улучшить код.

Использование перечислителя.

   
  1. private static void Main()
  2. {
  3. Console.ForegroundColor = ConsoleColor.White;
  4. foreach (var item in new YviEnumerable())
  5. {
  6. Console.WriteLine("postId: {0}, name: {1}, url: {2}, image: {3}, author: {4}, authorUrl: {5}", item.Id,
  7. item.Name, item.Link,
  8. item.Image, item.Author, item.AuthorUrl);
  9. }
  10. Console.ReadLine();
  11. }

На этом всё, жду(или не жду:) без разницы) конструктивных комментариев.

Кстати результат исполнения программы:

]]>
Fri, 24 Oct 2014 14:05:06 +0600Hes@yvision.kz (Hes)функциональное программированиеc#ienumerableyvisionпарсертрансформация данныхhttps://yvision.kz/post/435538https://yvision.kz/post/435538