Why Ruby?
-
Upload
dmitriy -
Category
Technology
-
view
423 -
download
1
description
Transcript of Why Ruby?
RUBYПочему его стоит выучить?
Ruby● http://ruby-lang.org● Динамический объектно-ориентированный язык
со строгой типизацией● И большим количеством сахара
Ruby
Динамический со строгой типизацией
● Тип задается при присваивании● Типы не приводятся автоматически к одному типу
["test"] + "test"TypeError: can't convert String into Array
Утиная типизация● Важен не тип объекта, а возможность запустить метод
у него.
Пример● a = [1, 2, 3]● max = nil● If a.respond_to?(:max)● max = a.max● elsif a.respond_to?(:each)● a.each{|a| max ||= a; max = a if max < a }● end
Объектно-ориентированный● Все является объектом● Даже примитивы● Даже методы● Даже классы
Классы● Всего лишь специальный объект● Объект, который создает экземпляры с
предопределенными методами и полями при помощи специального метода.
● У каждого объекта есть свойство #class который содержит ссылку на класс.
ПримерMyClass = Class.new(Object) do define_method(:test) do "Hello World!" endend
MyClass.new.testMyClass.new.class
Пример с сахаромclass MySweetClass def test "Hello World!" endend
MySweetClass.new.testMySweetClass.new.class
Про сахарattr_accessor :url, :version, :namedef name “My name is #{name}” end
def url=(value) @url = value if value[/\Ahttp/] @urlend
Про сахарarr.any?arr.compact!
def +(other) ..end
result = case awhen (1..10) "hi"when String "test"end
Расширяемость● Нельзя закрыть класс от наследования.● Каждый объект можно расширить.
Расширяемостьclass Test def test ”test” endendp (test = Test.new).test #”test”test.instance_eval do def test “magic” endEndp test.test # magic
Расширяемостьclass Test def do_smth(param) endend
class Test alias_method :do_smth, :do_smth_without_logging def do_smth(param) p param do_smth_without_logging endend
RUBY STYLE
Ruby-style● Писать как можно больше кода● и как можно меньше всякой фигни
Про всякую фигню● return● ;● ()● public/private/protected● else if● комментарии
Ruby-style● Писать как можно больше кода● и как можно меньше всякой фигни● Идти по пути наименьшего удивления● Наименования должны выражать сущность объекта
Например● AbstractSingletonProxyFactoryBean
Порождающие шаблоны программирования● Singleton● Factory● Prototype● Builder● FactoryMethod
Singletonclass A include Singletonend
Factorydef possible_objects {test: Test, sweet: SweetObject}end
def get_new_object(object) klass = possible_objects[object] klass.new if klassend
Prototype● {test: ‘for Ruby’}.clone
Ruby-style● Писать как можно больше кода● и как можно меньше всякой фигни● Идти по пути наименьшего удивления● Наименования должны выражать сущность объекта● Всё должно быть протестировано
Тестыrequire ’spec_helper’describe Balance do before do Deposit.create(amount: 120) Time.stub(:now).and_return('2010-04-02’.to_time) Deposit.create(amount: 110) end
its(:balance) { should == 230.0 }
it "calculates balance for selected date" do subject.date_balance('2010-04-02’).should == 110.0 endend
Результатrspec % --format=documentation
Balance calculates balance for selected date balance should eq 230.0
Finished in 0.01385 seconds2 examples, 0 failures
Еще пример● Feature: Tracking and logging external agent jobs
● We need Pantry to be able to track jobs and keep a record of each job's log output.
● Background:● Given an agent job has been triggered● And the agent is about to start the job
● Scenario: An agent registers a new job● When an agent has posts all the required job details● Then a response with the uri to the job should be received
Ruby-style● Писать как можно больше кода● и как можно меньше всякой фигни● Идти по пути наименьшего удивления● Наименования должны выражать сущность объекта● Всё должно быть протестировано● Код пишется для людей
Deploy
capistrano
set :scm, :gitset :scm_verbose, truenamespace :deploy do desc "Restart Apache" task :restart, roles: :app, except: { no_release: true } do run "touch #{File.join(current_path,'tmp','restart.txt')}" endend
Configuration managers● Chef● Puppet
Chef● Recipe
● windows_package node['sql_server'][pkg]['package_name'] do
● source node['sql_server'][pkg]['url']● checksum node['sql_server'][pkg]['checksum']● installer_type :msi● options "IACCEPTSQLNCLILICENSETERMS=#{node
['sql_server']['accept_eula'] ? 'YES' : 'NO'}"● action :install● end
RAILS & WEB FRAMEWORKS
Ruby on Rails● Июль 2004● MVC Framework● ActiveRecord для работы с базой данных● ActiveView&ActionController● ActionMailer● ActiveSupport
Ruby on Rails● Простой язык● Одинаковая структура для всех приложений
Структура├── Gemfile├── Gemfile.lock├── README.rdoc├── Rakefile├── app│ ├── assets│ │ ├── images│ │ ├── javascripts│ │ └── stylesheets│ ├── controllers│ ├── helpers│ ├── mailers│ ├── models│ └── views│ └── layouts
Структура── config│ ├── application.rb│ ├── database.yml│ ├── environments│ │ ├── development.rb│ ├── initializers│ ├── locales│ │ └── en.yml│ └── routes.rb├── config.ru├── db│ ├── migrate│ │ └── 20130613111514_test_migration.rb│ ├── schema.rb│ └── seeds.rb
Структура├── lib│ ├── assets│ └── tasks├── log├── public│ ├── 404.html│ ├── 422.html│ ├── 500.html│ ├── favicon.ico│ └── robots.txt├── result├── test├── tmp└── vendor └── assets ├── javascripts └── stylesheets
Ruby on Rails● Простой язык● Одинаковая структура для всех приложений● Простое ORM
ActiveRecordclass User < ActiveRecord::Base validates :username, presence: true, uniqueness: { case_sensitive: false }, length: { minimum: 2, maximum: 30 }, format: { with: USERNAME_REGEX, message: I18n.t('errors.attributes.username.invalid') }
has_many :mobile_devices, dependent: :destroyend
ActiveRecordUser.find(params[:id])User.find_by_username(params[:username])User.where(:username => params[:username])[email protected]_devices.find(params[:id])
Entry.select(..) .joins(:user, :transaction) .order("entries.created_at DESC, entries.sequence_id”)
Ruby on Rails● Простой язык● Одинаковая структура для всех приложений● Простое ORM● Легко писать тесты● Легко обновлять● Очень быстро можно начать работать● Много плюшек● Convention over configuration
Ruby on Rails● “Rails is omakase” DHH● Можно многое поменять
Sinatra● Очень простой фреймворк● Использовать только то, что надо● Быстрый
Padrino● Sinatra +
● генераторы● Возможность работать с большими приложениями
КАКИЕ БЫВАЮТ РУБИ?Различные интерпретаторы
MRI● 1.8.7 – 2008● 1.9.3 – 2011● 2.0.0 - 2013
Rubinius● С++ и Руби● Вышел в 2006● Последняя версия в 2011● RubySpec
JRuby● Вышел в 2001● Последняя версия в мае 2013 с экспериментальной
поддержкой Руби 2.0● Изначально поддерживали Rails
IronRuby● Объявлен в 2007● Последняя версия 2011
MacRuby● Руби на ObjectiveC
RubyMotion● Руби для iOS
Topaz● Руби на Питоне
Как учить?● http://tryruby.org/levels/1/challenges/0● http://railsforzombies.org/● Читать хороший код (rails, sinatra, rubinius, diaspora,
discourse, alphagov)
Книги
И самое интересное● Написать свою реализацию RSpec
Контакты
URL: www.acceptic.com
Software programming services andDedicated developers teams
E-mail: [email protected]
Tel.: +1 800 990 4370