Хм ... всё ещё не подобрал нормальный редактор ...

Posted on February 16, 2007
Сегодня пробовал EditPlus с руби раскраской ... пришлось правда чуть изменить раскраску под себя ... за 10 минут впринципе написал http://pad.tumalevich.pp.ru/ Плюс по сравнению с эклипсом - скорость работы ... минусы - отсутствие всяких фенечек ...

Drb и callback

Posted on February 16, 2007
Иногда надо чтоб сервер пнул клиента и он чтонить сделал. Например сервер запускает длительный процесс а потом пинает клиента что он завершён. Для этой цели и придуманы обратные вызовы. В Drb они делаются очень просто
Код сервера

require 'drb/drb'

#Слушаем на всех интерфейсах
URI="druby://:8787"

class Client
	include DRb::DRbUndumped

	def callback
		@client.callback
	end
	
	def connect(clnt)
		@client = clnt
	end

end

class ClientFactory
	def initialize
		@clients = {}
	end

	def hello(name)
		unless @clients.has_key? name
			@clients[name] = Client.new
		end
		return @clients[name]
	end
end


FRONT_OBJECT=ClientFactory.new
$SAFE = 1 
DRb.start_service(URI, FRONT_OBJECT)
DRb.thread.join
И код клиента:

require 'drb/drb'
SERVER_URI="druby://10.26.11.58:8787"

class MeWaitCallback
	include DRb::DRbUndumped

	def initialize(uri = 'druby://localhost:8787')
		DRb.start_service
		@clients_service=DRbObject.new_with_uri(uri)
		@client = @clients_service.hello("Zlo")
		@client.connect(self)
		@client.callback
	end
	
	def callback
		puts "Yooo Hooo!"
	end

end


MeWaitCallback.new
Вот и всё, всё очень просто ))

Удивительное рядом, или распределённые приложения на ruby

Posted on February 15, 2007
Некоторое время назад я пробовал себя в написании распределённых приложений ... всё закончилось довольно скучно и костылестроительно ... а сегодня читая мануалы по руби наткнулся на замечательную вещь - DRB. Итак:

Руби имеет собственный протокол для передачи между клиентом и сервером druby
Рассмотрим кратенький экзампл из мануала:
Сервер:

  require 'drb/drb'

  # The URI for the server to connect to
  URI="druby://:8787" #принимаем по всем интерфейсам на порт 8787

  class TimeServer
    def get_current_time
      return Time.now
    end
  end

  #Объект для экспорта
  FRONT_OBJECT=TimeServer.new

  $SAFE = 1   # Эвал нам не нужен, пока какой-то урод не прислал `rm -rf /`

  #Стартуем сервер
  DRb.start_service(URI, FRONT_OBJECT)
  # И ждём пока drb не завершился
  DRb.thread.join

Теперь код клиента:

  require 'drb/drb'

  # Куда цепляться
  SERVER_URI="druby://localhost:8787"

 #Стартуем сервер для ловли колобков (callback) ;) 
 DRb.start_service

  timeserver = DRbObject.new_with_uri(SERVER_URI)
  puts timeserver.get_current_time
И вуаля, получаем текущее время на сервере
В следующий раз я напишу о callbacks и передаче объектов

Создание генератора для Rails

Posted on February 10, 2007
По прежнему работая с Liquid я понял, что мне надоело писать код Drop`ов руками .... и решил сделать небольшой генератор.
Итак, в директории lib/ создаём generators
В ней размещаются все генераторы. Создаём в ней директорию liquid_drop
в ней нам необходимо создать наш генератор и шаблоны к нему в поддиректории templates/
Код генератора (liquid_drop_generator.rb)

class LiquidDropGenerator < Rails::Generator::Base
	attr_reader   :drop_name
	attr_reader   :actions

	def initialize(runtime_args, runtime_options = {})
	    super
	    @drop_name = args.shift || "example"
	    @actions = args
	end

	def manifest
		record do |m|
			 m.template 'drop.rb', File.join('app/drops',"#{drop_name}_drop.rb")
		end
	end
end
И код шаблона (templates/drop.rb)

class <%= drop_name %>Drop < Liquid::Drop

  def initialize(item) 
      @item = item
  end  

<% for action in actions -%>
  def <%= action %>
      
  end
  
<% end -%>

end
Конечно это очень простой генератор, но мне пока хватает и его ))
как всегда fast and dirty

Сравнение has_many :through и has_and_belongs_to_many

Posted on February 06, 2007
Для связи 2х моделей в Rails через таблицу связей имеется 2 типа связи habtm и has_many :through
Рассмотрим стандартный пример из Wiki:

1. has_and_belongs_to_many - Связь таблицей


#таблица связи
create_table "dancers_movies", :id => false do |t|
  t.column "dancer_id", :integer, :null => false
  t.column "movie_id",  :integer, :null => false
end
#и модели
class Dancer < ActiveRecord::Base
  has_and_belongs_to_many :movies
end

class Movie < ActiveRecord::Base
  has_and_belongs_to_many :dancers
end
Очень просто в использовании, таблица соединений имеет всего 1 ключ и 2 поля, больше полей использовать нельзя.

has_many :through - связь через модель


#таблица
create_table "appearances", do |t|
  t.column "dancer_id",      :integer, :null => false
  t.column "movie_id",       :integer, :null => false
  t.column "character_name", :string
  t.column "dance_numbers",  :integer
end
#модель
class Appearance < ActiveRecord::Base
  belongs_to :dancer
  belongs_to :movie
end

class Dancer < ActiveRecord::Base
  has_many :appearances, :dependent => true
  has_many :movies, :through => :appearances
end

class Movie < ActiveRecord::Base
  has_many :appearances, :dependent => true
  has_many :dancers, :through => :appearances
end
Связывающая модель является обычным объектом со всеми его плюсами и минусами (не следует забывать о потреблении памяти ;))

подведение результатов

итак, вот сравнение преимуществ и недостатков этих двух способов
habtm
Чтоhas_many :through
Primary Key-+
дополнительные параметры ассоциации-+
Полиморфизм-+

При составлении использовалась хорошая статья http://blog.hasmanythrough.com/2006/04/20/many-to-many-dance-off

установил highlight.js

Posted on February 05, 2007
Надоело писать неразборчивый код :)

def hello
return "world!"
end

Использование Drop в Liquid

Posted on February 05, 2007

Drops это очень хорошая вещь расширяющая возможности Liquid

Допустим мне необходимо сделать вывод информации о позициях каталога, каждая позиция имеет name, description и price

Для этого в app создаётся поддиректория drops в которой я создаю для модели дропа:


class ShopItemDrop < Liquid::Drop
  def initialize(item)
      @item = item
    end
    def name
      @item[:name]
    end
    def description
      @item[:description]
    end
    def price
      @item[:price]
    end
end

в модели shop_item пишу вызов дропа при преобразовании в Liquid
def to_liquid(options = {})
    ShopItemDrop.new self
end

После чего в отображении просто пишу:


{% for item in items %}
        {{item.name}}
        {{item.description}}
        {{item.price}}
{%endfor%}

Перезапускаю сервер ... oops ... ошибочка, конечно, rails ещё не знает где лежат дропы ...
открываем environment.rb и пишем следующую строчку  
config.loadpaths += %W( #{RAILSROOT}/app/drops )


установка Liquid в приложение.

Posted on February 05, 2007
Итак, для начала необходимо создать новое rails приложение
meg@MediaServer:~$ rails liquid_test
Затем необходимо установить плагин Liquid
meg@MediaServer:~$ cd liquid_test/vendor/plugins
meg@MediaServer:/home/meg/liquid_test/vendor/plugins$ svn export svn://home.leetsoft.com/liquid/trunk/liquid/
теперь можно создать простой контроллер для тестирование Liquid
meg@MediaServer:/home/meg/liquid_test$ script/generate controller hello index
Мы получили контроллер и отображение, переименуем расширение отображения в liquid и запишем внутрь следующее
Hello {{name}}
Затем добавим в контроллере

def index
@name = "UserAd"
end

Запускаем сервер и видим: Hello UserAd.
На этом пока что можно закончить

Применение шаблонного движка Liquid в Rails

Posted on February 05, 2007
При изучении RoR вначале мне очень не понравилось организация views, они меня очень смущали своими ASP тэгами и хотелось чего-то более привычного после PHP и Smarty. Как оказалось оно есть, и имя ему Liquid
Итак, синтакс шаблонов очень прост:
  • Простой вывод переменной шаблона делается так: Hello {{name}}
  • Фильтры вывода:
    Hello {{ 'tobi' | upcase }}
    Hello {{ 'tobi' | length }}
    Hello {{ '*tobi*' | textilize | upcase }}
    Hello {{ now | date: "%Y %h" }}
    Hello {{ 'Typo' | link_to: 'http://typo.leetsoft.com', 'Typo is a modern weblog engine' }}
  • Условия. Все условия имеют вид {% if условие %}
    Действие
    {% endif %}
  • Циклы:
    {% for item in array %} //действие {% endfor %}
В дальнейшем я опишу более подробно использование Liquid

Утро это зло

Posted on February 05, 2007

Каждый раз просыпаясь утром понимаю, что утро – зло. Так хочется поспать ещё немного, но надо вставать и идти в институт/на работу, а то опять чтонить сломается и придётся бежать … Скорее бы закончить институт … хотя для этого же надо сдать долги ;) а с ними немного проблемно….


Установка mephisto

Posted on February 05, 2007

typo что-то тупо не стал работать и я подался к mephisto … Посмотрим устроит ли он меня или я сам начну писать блог …