11.19.2009

xckd как всегда отжигает. жизненно и в тему. Some engineer out there has solved P=NP and it's locked up in an electric eggbeater calibration routine. For every 0x5f375a86 we learn about, there are thousands we never see.

10.24.2009

asp.net, website, objectdatasource

В asp.net есть такой тип проекта WebSite. Он отличается от WebApplication тем, что проектный сайт не создается, любой попавшый в папку файл добавляется в сайт, и самое главное - сайт не собирается в отдельную сборку. На продакшн сайт можно добавлять новые странички не компилируя их (ну есть конечно же предкомпиляция сайта, но см. далее). Каждая страничка компилируется через iis сервер в собственную сборку с рандомным именем. Как это разруливает сервер - загадка.

Для простой логики где все находится в пределах одной страницы все окей, а вот когда требуется вызвать код находящийся на другой страничке - начинаются проблемы: одна страничка ничего не знает о другой (т.к. находится в собственной сборке). Обычное решение - выносить такой нужный код в отдельную собственную сборку, типа библиотеки, закинуть ее в bin директорию сайта, подключать ее в страничках сайта и использовать в коде. Хорошо то оно хорошо. А что делать если ну никак не хочется выносить одну единственную функцию в библиотеку, код которой нужен только на одной единственной страничке?

Пример - нужно реализовать bind грида через object data source, и не через что-либо иное (такое может понадобится для использования фишек грида типа редактирования, удаления в табличке, сортировки, пейджинга и т.п.). Проблема сводится к тому что в SelectMethod нужно написать имя метода, в SelectParameters - параметры, а в TypeName - полное название типа где находится метод. А класс лежит в своей собственной сборке, а имя генерируется рандомно. Единственное решение проблемы - динамически заполнять поле TypeName на этапе загрузки страницы. Вот финальный код:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="myprojectclass.aspx.cs" Inherits="myprojectclass" %>

<asp:GridView ID="gridView1" runat="server" DataSourceID="objectDataSource1" AutoGenerateColumns="True" />
<asp:ObjectDataSource ID="objectDataSource1" runat="server" SelectMethod="GetData" TypeName="" ></asp:ObjectDataSource>

public partial class myprojectclass : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
         // ...
         objectDataSource1.TypeName = String.Format("{0}, {1}", this.GetType().FullName, this.GetType().Assembly);
         gridView1.DataBind();
    }
    
    public System.Collections.Generic.List<DataItem> GetData() {
         // ...
    }
}

Повторюсь - это будет работать в пределах одной страницы, код другой странички получить не получится. Только через собственную сборку. Выводы: 1. никогда не использовать WebSite 2. использовать только WebApplication - так как все получается логично и понятно 3. По возможности никогда не использовать ASP.NET - есть другие более удобные инструментарии веб-разработки

10.18.2009

Подсветка синтаксиса в блоге

Прикрутил к блогу подсветку синтаксиса кода. Некоторое время я провел за поисковиком, все примеры были не очень и в основном старые. Нашел кое-что подходящее на heisencoder.net. В итоге и использовал эту компоненту syntaxhighlighter. Еще есть старый репозиторий на гугл-коде. Жалко что пример на том блоге устарел и почему-то у меня не заработал. Благо у автора компоненты очень подробная док-ция Компонента представляет собой набор javascript-ов и css шаблонов, заходим на http://alexgorbatchev.com/pub/sh/ выбираем нужную версию и качаем. Можно и не качать, а использовать прямые ссылки на хостящиеся файлы. В общем внутри head-а странички вставляем следующий код:
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushXml.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCpp.js' type='text/javascript'/>

<script type='text/javascript'>
  SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';
                SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.defaults['gutter'] = true;
                SyntaxHighlighter.all();
</script>
Тем самым мы добавили нужные стили (у меня используется дефолтный, но вообще доступно несколько) и скрипты (здесь я добавил html, cpp, c#), настроили компоненту должным образом. За подробными комментариями по назначению, списку всех параметров и всех возможных скриптов - на сайт производителя. Потом в html-код сообщения добавляем
<pre class="brush: cpp; toolbar: true;">
 #include <iostream>
    int main() {
  std::cout << "hello" << std::endl;
 
 }
</pre>
P.S. Главное не забывать ескейпить символы...

10.15.2009

Индусы среди нас

Один человечек написал подобный код:
  class Item {
    public static void UpdateItem(Item _item) {
    // ...
    }
  }

  Item it;
  // ...
  Item.UpdateItem(it);
Попахивает безграммотностью. Не логично использовать статический метод который принимает экземпляр собственного класса. Я попросил человечка избавиться от статического метода. Код был переписан вот в это:
  class Item {
    public void UpdateItem(Item _item) {
    // ...
    }
  }
  
  Item it;
  // ...
  new Item().UpdateItem(it);
Да, оказывается у некоторых в крови индусские гены и они в тайне по ночам молятся шестируким богам. И почему нельзя сделать вот так, по простому:
  class Item {
    public void UpdateItem() {
    // ...
    }
  } 

  Item it;
  // ...
  it.UpdateItem();

8.19.2009

Не вероятно, но факт

Есть десктоп, на него давно заведена сетка, полностью настройка по dhcp и т.п. Есть ноут, сиротливо лежащий без инета. Было решено завести на нем сетку, для начала хотя бы через вторую сетевуху (покупать вайфай точку лом). К тому же на ноуте упала винда и не хотела восстанавливаться. Взял с полки старенькую сетевуху от dlink-а, воткнул ее в комп. Убунта правильно ее определила, корректно добавила в устройства и сделала на нее интерфейс. Как по инструкции с гугла, во вторую сетевуху втыкаем провод, другой конец заводим в ноут. Т.к. операцонки на ноуте нету - стартуем с live-cd. на десктопе с помощью ifconfig -a получаем имя нового интерфейса (eth1). на десктопе в /etc/network/interfaces пишем: auto lo eth0 eth1 iface lo inet loopback iface eth0 inet dhcp iface eth1 inet static address 195.168.0.1 netmask 255.255.255.0 network 195.168.0.0 broadcast 195.168.0.255 на ноуте: auto lo eth0 iface lo inet loopback iface eth0 inet static address 195.168.0.120 netmask 255.255.255.0 getway 195.168.0.1 перезапускаем сетку и там и там: sudo /etc/init.d/networking restart на ноуте делаем: ping 195.168.0.1 в ответ получаем: destination host unreachable. Че за нах?!! Спокойно, пробую еще несколько раз... может быть с проводом что-то не так, да нет только что друзья обжали и просветили. Лезем в dmesg | grep eth ... видим: eth1 бла-бла-бла "no link". Че за нах?!! Провод же воткнут правильно!! Ладно, забиваю - сетевуха очень старая - может быть в ней косяк. И правда - выдергиваю шнур из второй карточки и вставляю в первую - пинг пошел!! В топку карточку значитсо. На первый раз с меня хватило - решил просто перелить данные с ноута на десктоп. Поставил ftp-сервер, под дефолтными настройками заюзал с ноута - и перелил инфу. Забил. Некоторое время спустя появилась у меня другая карточка. На вид более новая. Втыкаю ее, настраиваю. Та жа лажа - destination host unreachable и "no link". Ну все, меня начинает коробить. Меняю на десктопе местами шнуры и конфиги, включаю - пинг пошел, локальная сетка провайдера работает!! Не вероятно, но факт. В чем была конкретно проблема - мне не понятно. После этого чтобы не парить мозг - ставлю на десктопе проксю 3proxy, настраиваю на айпишник моего ноута. Настраиваю ноут на прокси - вуаля - все пашет как надо, инет есть на двух компах. Потом была установка на ноут полноценной оси, но это уже другая история.

1.18.2009

How to Use Constraints in Generics

Взято из книжки по подготовке экзамена microsoft "MCTS Self-Paced Training Kit (Экзамен 70-536)", Глава 1 (Framework fundamentals), Урок 3 (What are generics). How to Use Constraints Generics would be extremely limited if you could only write code that would compile for any class, because you would be limited to the capabilities of the base Object class.To overcome this limitation, use constraints to place requirements on the types thatconsuming code can substitute for your generic. Generics support four types of constraints: - Interface Allow only types that implement specific interfaces to use your generic. - Base class Allow only types that match or inherit from a specific base class to use your generic. - Constructor Require types that use your generic to implement a parameterless constructor. - Reference or value type Require types that use your generic to be either a reference or value type. Use the As clause in Visual Basic or the where clause in C# to apply a constraint to a generic. Разберемся - для generic мы можем выставлять ограничение с помощью ключевого слова where, типа как далее:
class Abc<T> where T : IDisposable
{ ... }
Ну это понятно, теперь разберемся с самими ограничениями, с первыми двумя - все и так понятно, а вот на последние два авторы как-то забыли объяснить и дать пример. 1. parameterless constructor - требование безпараметрического конструктора. По-суть очень полезно, если внутри своего класса вы хотите создавать новые экземпляры обобщенного класса. Все очень просто, нужно написать new(). Кстати без данного ограничения вы не сможете написать T it = new T()... :)
class Abc<T> where T : new()
{
 public void DoSmth()
 {
         T it = new T();
 }
}
2. Reference or value type. Тоже может быть очень полезным - так как мы можем полностью отсечь применения типа Abc<int> и т.д. Тут сложнее: для referenced type должно идти ключевое слово class, для value type - ключевое слово struct.
class Abc<T> where T : class
{ ... }

class Cba<T> where T : struct
{ ... }
Честно говоря, когда я узнал что так можно делать - у меня был шок. Сразу же разрешилось несколько проблем в проектах :) Надеюсь кому-нибудь это тоже пригодится.