Ruby: всякая всячина

Продолжаю погружаться в мир Ruby. Для систематического рассказа пока не время, но путевых заметок уже накопилось, пора записывать для памяти.


1. При попытке установить gem на Ubuntu может возникать сообщение об ошибке:

extconf.rb:8:in `require’: no such file to load — mkmf (LoadError)
from extconf.rb:8
ERROR: While executing gem … (RuntimeError)
ERROR: Failed to build gem native extension.

Это означает, что не установлен пакет ruby###-dev, где ### — версия Ruby (текущая стабильная — 1.8). можно установить его, а можно сразу ruby-full, который гарантирует полную установку последней стабильной версии.

2. Просмотреть документацию локально установленных gems можно с помощью gem_server. После его запуска документация доступна по адресу http://localhost:8808.

3. gem renum дает возможность определять перечислимые типы:

enum :Status, %w( NOT_STARTED IN_PROGRESS COMPLETE )
 
enum :Size do
 
  Small("Really really tiny")
  Medium("Sort of in the middle")
  Large("Quite big")
 
  attr_reader :description
 
  def init description
    @description = description
  end
 
end
 
module MyNamespace
  enum :FooValue, [ :Bar, :Baz, :Bat ]
end

4. gem interface дает возможность определять интерфейсы в стиле Java (как набор методов) и проверять, что класс заданные интерфейсы реализует (конечно, типы параметров не специфицируются):

   require "interface"
 
   MyInterface = interface{
      required_methods :foo, :bar, :baz
   }
 
   # Raises an error until 'baz' is defined
   class MyClass
      def foo
         puts "foo"
      end
      def bar
         puts "bar"
      end
      implements MyInterface
   end

5. Две попытки снабдить Ruby средствами строгой типизации (но не статической!):
gem strongtyping:

      require 'strongtyping'
      include StrongTyping
 
      def foo(a, b)
         expect(a, String, b, Numeric)
         ...
      end

types:

typesig String, [Array, Hash]
def example2(string, array_or_hash)
  # ... here, we know that string is a String, and array_or_hash
  # is either an Array or a Hash (or a subclass thereof) ...
end

Eivind Eklund, автор types, утверждает, что его кунг-фу сильнее. И на первый взгляд это действительно так.

Все перечисленное меня больше интересует как способ описать контракт, а не проверить что-то во время работы программы.

6. Кстати, о контрактах. gem rubydbc позволяет добавлять в код пре- и постусловия:

class Foo
   include DesignByContract
 
   pre(:sqrt, "value must be >= 0") { |v| v >= 0 }
 
   pre("divisor must be != 0") { |dividend, divisor| divisor != 0 }
   post { |result, a, b| a - b * result < 1e-3 }
   def div(dividend, divisor)
      dividend / divisor
   end
 
   def sqrt(value)
      Math.sqrt value
   end
 
   post(:sqrt, "error is greater than expected") { |result, value|
         result * result - value < 1e-3
   }
end

7. gem rspec — must have для тестов. А без тестов в Ruby никуда…

25.03.2008  Метки:   Рубрики: Разработка, Языки

Написать комментарий