18. Ruby core и stdlib. Външни зависимости. Полезни библиотеки

18. Ruby core и stdlib. Външни зависимости. Полезни библиотеки

18. Ruby core и stdlib. Външни зависимости. Полезни библиотеки

21 декември 2015

Днес

Предстоящи теми догодина

Изпитни дати и втори тест

Проекти

важни срокове

Прототипи

Въпроси за проектите?

Ще продължим с Ruby core & stdlib.

Ruby core

Struct

Struct

пример от документацията

Виждате, че може да добавите и свои методи там

Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end

dave = Customer.new('Dave', '123 Main')

dave.name     # => "Dave"
dave.address  # => "123 Main"
dave.greeting # => "Hello Dave!"

Struct

Обектите от тип Struct приличат на колекции (хешове):

Customer = Struct.new(:name, :address, :zip)
john = Customer.new('John Doe', '123 Maple, Anytown NC', 12345)

john.name      # => "John Doe"
john['name']   # => "John Doe"
john[:name]    # => "John Doe"
john[0]        # => "John Doe"

john.length    # => 3
john.each      # => #<Enumerator: #<struct Customer name="John Doe", address="123 Maple, Anytown NC", zip=12345>:each>

Приложение на Struct

Удобно е да се ползва в тестове. За production код – по-рядко.

Comparable

Comparable

пример

class Money
  include Comparable

  attr :amount, :currency

  def initialize(amount, currency)
    @amount, @currency = amount, currency
  end

  def <=>(money)
    return unless currency == money.currency
    amount <=> money.amount
  end
end

Money.new(15, :BGN) < Money.new(30, :BGN) # => true

Marshal

Marshal

пример

data = [42, :answer, {foo: 'bar'}]

serizlized = Marshal.dump data

serizlized                       # => "\x04\b[\bi/:\vanswer{\x06:\bfooI\"\bbar\x06:\x06ET"
Marshal.load(serizlized) == data # => true
Marshal.load(serizlized)         # => [42, :answer, {:foo=>"bar"}]

Marshal

употреба и бележки

IO и File

File - два примера

Прочитане на цял файл като низ:

File.read('/etc/resolv.conf') # => "The contents of the file as a string."

Отваряне на файл, работа с обекта и автоматично затваряне на файла при излизане от блока:

File.open('foo/bar.txt', 'w') do |file|
  file.write 'Some data.'
  file.puts  'Some other data, with a newline at the end.'
  file.puts  'File will be closed automatically, even in case of an exception in the block.'
end

RubyVM::InstructionSequence

RubyVM::InstructionSequence

пример

code = 'puts ["a" * 10].first'
compiled = RubyVM::InstructionSequence.compile(code)
puts compiled.disasm

Резултат:

== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace            1                                               (   1)
0002 putself
0003 putstring        "a"
0005 putobject        10
0007 opt_mult         <callinfo!mid:*, argc:1, ARGS_SKIP>
0009 newarray         1
0011 opt_send_simple  <callinfo!mid:first, argc:0, ARGS_SKIP>
0013 opt_send_simple  <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>
0015 leave

RubyVM::InstructionSequence

още един пример

puts RubyVM::InstructionSequence.compile('a, b = 1, 2').disasm

Можем да видим, че a, b = 1, 2 минава през създаване на един обект тип Array:

== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
local table (size: 3, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, keyword: 0@4] s1)
[ 3] a          [ 2] b
0000 trace            1                                               (   1)
0002 duparray         [1, 2]
0004 dup
0005 expandarray      2, 0
0008 setlocal_OP__WC__0 3
0010 setlocal_OP__WC__0 2
0012 leave

Стандартната библиотека на Ruby

Налични библиотеки

abbrev       base64          benchmark    bigdecimal          cgi            cmath
coverage     csv             curses       date                dbm            debug
delegate     digest          dl           drb                 e2mmap         English
erb          etc             extmk        fcntl               fiddle         fileutils
find         forwardable     gdbm         getoptlong          gserver        io/console
io/nonblock  io/wait         ipaddr       irb                 json           logger
mathn        matrix          minitest     minitest/benchmark  minitest/spec  mkmf
monitor      mutex_m         net/ftp      net/http            net/imap       net/pop
net/smtp     net/telnet      nkf          objspace            observer       open-uri
open3        openssl         optparse     ostruct             pathname       pp
prettyprint  prime           profile      profiler            pstore         psych
pty          racc            racc/parser  rake                rdoc           readline
resolv       resolv-replace  rexml        rinda               ripper         rss
rubygems     scanf           sdbm         securerandom        set            shell
shellwords   singleton       socket       stringio            strscan        sync
syslog       tempfile        test/unit    thread              thwait         time
timeout      tk              tmpdir       tracer              tsort          un
uri          weakref         webrick      win32ole            xmlrpc         yaml
zlib

Какво сме ползвали досега от stdlib?

OpenStruct

OpenStruct - пример

require 'ostruct'

john = OpenStruct.new
john.name = 'John Doe'
john.age  = 33

john.name     # => "John Doe"
john.age      # => 33
john.address  # => nil

Полезни Ruby gem-ове и поуки

Third-party software – disclaimer

Долното е извадка от GNU GPL лиценза за отворен код:

15. Disclaimer of Warranty.

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Third-party software – disclaimer

Долното е извадка от GNU GPL лиценза за отворен код:

15. Disclaimer of Warranty.

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

“AS IS” WITHOUT WARRANTY OF ANY KIND

Ние, програмистите, не вярваме на собствения си код, та какво остава за чуждия такъв?

Така и трябва. Колкото по-малко зависимости от чужд (third-party) код – толкова по-добре.

Изобщо, колкото по-малко код, откъдето и да е дошъл – толкова по-добре. Но това е друга тема.

От друга страна, не може да си напишем всичко. Трябва да стъпим на нещо. И трябва да знаем как да изберем на какво.

Популярни gem-ове

статистика от rubygems.org

rubygems.org/stats

Като изключим "помощни" gem-ове, най-популярният е Rails (с десетки милиони изтегляния)

Откриване на нови Ruby Gems

Оценка качеството на съществуващи gem-ове

Инсталация под Windows

RubyDoc

Rails

rubyonrails.org

RuboCop

https://github.com/bbatsov/rubocop

Sidekiq

https://github.com/mperham/sidekiq

ActiveSupport

https://github.com/rails/rails/tree/master/activesupport

ActiveRecord

https://github.com/rails/rails/tree/master/activerecord

ActiveRecord-Sinatra

https://github.com/janko-m/sinatra-activerecord

Curses

command-line UIs

https://github.com/ruby/curses

Thor

https://github.com/erikhuda/thor

CarrierWave и Paperclip

https://github.com/carrierwaveuploader/carrierwave

https://github.com/thoughtbot/paperclip

Kaminari и will_paginate

https://github.com/amatsuda/kaminari

https://github.com/mislav/will_paginate

MiniMagick

https://github.com/minimagick/minimagick

CanCan

https://github.com/ryanb/cancan

Devise

https://github.com/plataformatec/devise

Bcrypt-Ruby

https://github.com/codahale/bcrypt-ruby

ActiveAdmin

https://github.com/gregbell/active_admin

Nokogiri

https://github.com/sparklemotion/nokogiri

SASS

https://github.com/nex3/sass

SimpleForm и Formtastic

https://github.com/plataformatec/simple_form

https://github.com/justinfrench/formtastic

Capistrano

https://github.com/capistrano/capistrano

Deploy WordPress with Capistrano!

Passenger, Unicorn, Thin, Puma

https://github.com/phusion/passenger

Fog

https://github.com/fog/fog

Bundler

https://github.com/bundler/bundler или http://bundler.io

Практически задължително за всеки проект, който има нужда от други gem-ове.

Обобщение

String#%

бонус слайдове

String#%

пример с позиционни аргументи

Когато имаме повече от една стойност за интерполация, трябва да подадем списък:

'%02d' % 7                             # => "07"
'%02d:%02d:%02d' % [19, 5, 2]          # => "19:05:02"

name = 'Пешо'
'Здравей, <strong>%s</strong>!' % name # => "Здравей, <strong>Пешо</strong>!"

String#%

пример с именувани аргументи

template = '
  <html>
  <head>
    <title>%{title}</title>
  </head>
  <body>
    %{content}
  </body>
  </html>
'

variables = {
  title:   'String Interpolation',
  content: 'Made easy by Kernel.sprintf.',
  foobar:  'Extra keys are not an issue.'
}

template % variables # => "\n  <html>\n  <head>\n    <title>String Interpolation</title>\n  </head>\n  <body>\n    Made easy by Kernel.sprintf.\n  </body>\n  </html>\n"

Въпроси