25 января 2011 г.

Кирилица в проектах ruby NetBeans

Кратко, суть проблемы:
В проекте Ruby IDE Netbeans  под Windows не отображается кирилица. В то время, как с NetBeans под Убунтой такого небыло - кирилица выводилась без каких-либо проблем.
Решение - необходима настройка проекта ruby:
[окошко "Projects"]=>ПКМ на [названии вашего проекта]=>[Properties]=>[Sources] в открывшемся окне, слева=>[Encoding]выпадающее меню в самом низу=>выбрать интересующую кодировку. Я выбрал Windows-1251.
Перезапуск NetBeans. Все.

13 января 2011 г.

Пример создания пользовательского компонента Битрикс: Корпоративные телефоны.

Введение
Приведем пример создание компонента Битрикса на примере создания компонента «Корпоративные телефоны». Т. е. допустим у нас есть несколько телефонов и в разных разделах необходимо их как-то связано представить общественности (Рис. 1). Причем  имеет смысл выбирать не по одному телефону, а к примеру телефон начальника и его помощника.

Рис. 1
Первым делом расмотрим код вызова компонента и структуру директорий компонента.


<?
$APPLICATION->IncludeComponent("ns_ccom:telefon.bank", ".default", array(
"IBLOCK_ID" => "1",
"SELECTTELEFON" => array(
0 => "KS",
1 => "KP",
),
"SELECT_FIRST" => "Y",
"CACHE_TYPE" => "N",
"CACHE_TIME" => "3600"
),
false
);
?>
Листинг 1.
В листенге 1 в литерной переменной "ns_ccom:telefon.bank" передается необходимая информация для запуска компонента  — пространство имен и  имя компонента Битрикс (формат вызова  - «пространство имен: имя компонента»).
В свою очередь эта запись коррелирована с файловой системой компонента(ов) в Битриксе. Так все компоненты битрикса располагаются в папке /bitrix/components/, а с учетом пространства имен и имени компонента путь до файлов компонента  будет иметь следующий вид:
 /bitrix/components/ ns_ccom/telefon.bank/ (1)
Отсюда следует первый вывод — для того, чтобы создать компонент необходимо воспроизвести путь (1) в файловой системе на хосте.
Литерная переменная ".default" – соответствует о вызове необходимого шаблона компонента. Остальные переменные в массиве array(...) дополнительные параметры компонента Битрикса.
Теперь обратим внимание на файловую структуру компонента относительно пути /bitrix/components/:
[ns_ccom]
[date.current]
[templates]
[.default]
template.php
component.php
.parameters.php
.description.php
Листинг 2 (в квадратных скобках указаны имена директорий)
Замечание: В листинге 2 перечислены основные файлы и папки. Так же в директории date.current могут находится (необязательно):
Директория help -  для хранения файлов файлы помощи по компоненту;
Директория install -  для скриптов инсталляции/деинсталляциии компонента (install.php / uninstall.php);
Директория lang - Нужна для поддержки мультиязычности в компоненте.   
В папке templates размещается шаблон отображаемого компонента. Соответственно в папке .default размещен компонент по умолчанию (см. Листинг 1). 
Пройдемся по файлам
component.php -  Основной исполняемый файл компонента, отвечает за определение состояния модели данных компонента. Проще говоря, наполняет переменную $arResult
.parameters.php - Параметры компонента. Используется для определения параметров комонента (рис. 2). Результат работы переменная $arParams. 
description.php — Описание компонента
template.php — Код шаблонна





Рис. 2
component.php
<?
if(!defined("B_PROLOG_INCLUDED")||B_PROLOG_INCLUDED!==true)die();
if ($this->StartResultCache(3600))
{
$iblock_id = $arParams['ID'];
$arFilter = array('IBLOCK_ID'=>$iblock_id);
//Заполняем содержимым:
$arResult["KS"]="+7(812) 498-36-33";
$arResult["KP"]="+7(812) 325-40-06 доб. 120";
$arResult["CALL"]="+7(812) 325-40-06";
$this->IncludeComponentTemplate();
}
?>
Листинг 2
Вызов метода IncludeComponentTemplate инициализирует и подключает шаблон компонента Битрикса, а  вызов метода die в контексте условного оператора if запрещает вызов файла component.php  независимо от контекста страницы размещения компонента (через адресную строку).
 .parameters.php

<?
if(!defined("B_PROLOG_INCLUDED")||B_PROLOG_INCLUDED!==true)die();
$arComponentParameters = array(
'PARAMETERS' => array(
'IBLOCK_ID' => array(
'NAME' => 'Id инфоблока',
'TYPE' => 'STRING',
'MULTIPLE' => 'N', //Разрешить множественный выбор
'PARENT' => 'BASE',//Раздел настроек
),
'CACHE_TIME' => array('DEFAULT'=>3600),
"SELECTTELEFON" => Array(
"PARENT" => "BASE", //Раздел настроек
"NAME" => "TELPARAM", //Название
"TYPE" => "LIST", //Тип поля
"MULTIPLE" => "Y", //Разрешить множественный выбор
"ADDITIONAL_VALUES" => "N", //Разрешает добавку своих значений к списку
"VALUES" => array(
"KS" => "Кузнецов Сергей", //Пункты для выбора в списке
"KP" => "Кузнецов Павел",
"CALL" => "Официальный телефон банка",
),
"DEFAULT" => "CALL", //Значение по умолчанию
"REFRESH" => "Y", //Отображает кнопку «ОК» для обновления результатов (к примеру при выборе инфоблоков из типов инфоблоков)
),
'SELECT_FIRST' => Array(
'PARENT' => 'BASE',
'NAME' => "Выделять первый номер",
'TYPE' => 'CHECKBOX',
)
)
);
?>

Листинг 3.
В этом файле заполняем хэш таблицу $arComponentParameters которая коррелирует с переменной $arParams, которая доступна для вызова в файлах template.php и component.php.
Ключ 'PARAMETERS' отвечает за наполнение полей на  рис. 1. Как видно для управления доступно 4 опции:
IBLOCK_ID — определяет Id инфоблока (пока в этом компоненте не требуется, но пусть будет ). Тип поля  String;
CACHE_TIME – параметры кэширования;
SELECTTELEFON – Выбор владельца телефона (вообщем чьи телефоны отображать). Тип поля LIST
SELECT_FIRST – параметр для определения выделять ли первый номер телефона из списка. Тип  CHECKBOX.
Пример работы с этими полями будет продемонстрирован, когда дойдем до файла template.php
 .description.php:
В качестве пояснения по этому файлу процитируем из материалов центра разработки (http://dev.1c-bitrix.ru/community/blogs/components2/133.php).
В файле .description.php содержится описание компонента. Это описание применяется для работы с компонентом из среды Битрикс (например, в визуальном редакторе), а так же при работе в режиме редактирования сайта. При работе самого компонента (при обращении к странице, на которой расположен компонент) описание не используется и файл .description.php не подключается.

<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arComponentDescription = array(
"NAME" => 'BankTelefons',
"DESCRIPTION" => 'Список телефонов',
"ICON" => "",
"CACHE_PATH" => "Y",
"PATH" => array(
"ID" => "content", //Главный раздел компонентов, может принимать значения (service, utility, content, communication, e-store)
),
);
?>

Листинг 4
template.php



<style type="text/css">
#telefon_show{
background-color:none;
text-align:center;
}
#telefon_show p.first, #telefon_show p.usual{
font-family: Verdana;
color:#e63500;
}
#telefon_show p.first{
font-size:20px;
font-weight:bold;
padding:2px 0 2px 0;
}
#telefon_show p.usual{
font-size:12px;
font-weight:normal;
}
#telefon_show div.telefon_info{
font-size:15px;
font-weight:bold;
font-family: Verdana;
color:#585858;
}
</style>
<div id="telefon_show">
<div class="telefon_info">Появились вопросы, звоните:</div>

<?
/*Если в $arComponentParameters в качестве типа параметра задавался тип списка ('TYPE'=> 'LIST'),
то получим массив, который можно обработать следующим образом*/
foreach($arParams['SELECTTELEFON'] as $index=>$listParam)
{
//$listParam соответсвует ключу из хэш таблицы VALUES (parameters.php)
$mes="<p";//Сформируем строку которую будем выводить...
if (($arParams['SELECT_FIRST']=='Y')&&($index==0))
$mes.=" class='first'";//Если поставлена метка "Выделить первую строку" и строка первая
else $mes.=" class='usual'";
$mes.=">".$arResult[$listParam]."</p>";
echo $mes;//Печатаем строку
}
?>
<a href="/kontakti/">Как доехать до офиса?</a>
</div>

Листинг 5
В листинге 5 следует обратить внимание на цикл foreach, где происходит обращение к элементу $arParams['SELECTTELEFON'] и $arParams['SELECT_FIRST'] из .parameters.php
В качестве вывода:
Разбиение компонента по решаемым задачам на отдельные файлы до конца не решает  проблему сопровождения кода. Как видно из файлов components.php и template.php в шаблоне не удается вынести логику поведения за рамки представления. Файл components.php не имеет возможности выбора необходимого представления и делегирует эти полномочия пользователю при выборе шаблона компонента.

12 января 2011 г.

puts("there's more than one way to do it. ")

Небольшой пост на тему необходимости использовать плюшек языка(ов) на примере использования унарного амперсанда в Ruby.
Не будем брызгать слюной, сразу перейдем к примерам:
# a) перебираем элементы массива (1..10)
# b) применение лямбда функции ко всем элементам этого массива при помощи &
# Подопытная лямбда
test_lam=lambda{|inPut|
  puts("#{inPut}: #{inPut**2}");
  inPut**2 # В качестве возвращаемого значения
  }
# синтаксис с &
buf=(1..10).to_a.map &test_lam
# классический эквивалент
buf2=(1..10).to_a.map{|input| test_lam.call(input)}

Результат, предсказуем:
1: 1
2: 4
3: 9
4: 16
5: 25
6: 36
7: 49
8: 64
9: 81
10: 100
# Еще один пример
buf2=[1, 2, 3].map(&:to_s)
p buf2 # => ["1", "2", "3"]
# Эквивалент:
p [1, 2, 3].map { |i| i.to_s }
Что лучше? В сети нашел наводящий на мысли бенчмарк на эту тему
# Небольшой Бенчмарк: (http://blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand,
# http://m.onkey.org/let-s-start-with-wtf )
# traditional calls (with a block as in obj.each {|e| e.method_name }) 
# И Унарный амперсаендd to a Proc (like obj.each(&:method_name)).
require 'benchmark'
require 'rubygems'
require 'active_support'
array = [ 1, 'ab', :dog, 3.8 ]
COUNT = 100_000
Benchmark.bmbm(2) do |test|
  test.report('Using Symbol#to_proc') do
    COUNT.times do
      array.map(&:to_s)
    end
  end
  test.report('Standard call') do
    COUNT.times do
      array.map {|e| e.to_s }
    end
  end
end


Полученный результат
=begin
Rehearsal --------------------------------------------------------
Using Symbol#to_proc   1.125000   0.000000   1.125000 (  1.125000)
Standard call                 0.578000   0.000000   0.578000 (  0.578000)
----------------------------------------------------- total: 1.703000sec


                                          user     system      total        real
Using Symbol#to_proc   1.015000   0.000000   1.015000 (  1.015000)
Standard call                0.563000   0.000000   0.563000 (  0.563000)
=end

Может быть показания спидометра и не являются доказательством правильности курса, но примеры с использованием амперсанда проигрывают по времени исполнения «классическому» стилю.