window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster już istnieje') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Ruby Domain Specific Language - The Codest
The Codest
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Branże
    • Fintech i bankowość
    • E-commerce
    • Adtech
    • Healthtech
    • Produkcja
    • Logistyka
    • Motoryzacja
    • IOT
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
Strzałka w tył WSTECZ
2018-12-14
Software Development

Ruby Domain Specific Language

Bartłomiej Maziarz

Odnosząc się do definicji, DSL (Domain Specific Language) to język komputerowy wyspecjalizowany do konkretnej domeny aplikacji. Oznacza to, że został opracowany w celu zaspokojenia określonych potrzeb.

Czytając ten artykuł dowiesz się czym jest DSL i co ma wspólnego z Ruby.

DSL, witamy!

Odnosząc się do definicji, DSL (Domain Specific Language) to język komputerowy wyspecjalizowany do określonej domeny aplikacji. Oznacza to, że został opracowany w celu zaspokojenia określonych potrzeb. Istnieją dwa rodzaje DSL:

  • An zewnętrzny DSL, który wymaga własnego parsera składni. Dobrym znanym przykładem może być język SQL - pozwala on na interakcję z bazą danych w języku, w którym baza danych nie została utworzona.

  • An wewnętrzny DSL, który sam nie ma własnej składni, ale zamiast tego używa składni danego języka programowania.

Jak można się domyślić, skupimy się na drugim typie DSL.

Co to robi?

Zasadniczo, korzystając z metaprogramowania Ruby, można stworzyć własny mini-język. Metaprogramowanie jest techniką programowania, która pozwala na napisanie kod dynamicznie w czasie wykonywania (w locie). Możesz być tego nieświadomy, ale prawdopodobnie używasz wielu różnych DSL każdego dnia. Aby zrozumieć, co może zrobić DSL, spójrzmy na kilka poniższych przykładów - wszystkie mają jeden wspólny element, ale czy potrafisz go wskazać?

Routing w Railsach

Rails.application.routes.draw do
root to: 'home#index'

resources :users do
get :search, on: :collection
end
end
```

Każda osoba, która kiedykolwiek korzystała z Railsów zna config/routes.rb gdzie definiujemy trasy aplikacji (mapowanie między czasownikami HTTP i adresami URL do akcji kontrolera). Ale czy kiedykolwiek zastanawiałeś się, jak to działa? W rzeczywistości jest to po prostu kod Ruby.

Factory Bot

 FactoryBot.define do
   factory :user do
     firma
     sequence(:email) { |i| "user_#{i}@test.com" }
     sequence(:first_name) { |i| "User #{i}" }
     last_name 'Test'
     role 'manager'
   end
 end

Pisanie testów często wymaga tworzenia obiektów. Dlatego też, aby uniknąć straty czasu, naprawdę dobrym pomysłem byłoby maksymalne uproszczenie tego procesu. To jest właśnie to FactoryBot to łatwe do zapamiętania słowa kluczowe i sposób opisu obiektu.

Sinatra

require 'sinatra/base'

class WebApplication < Sinatra::Base
get '/' do
'Hello world'
end
end
```

Sinatra to framework, który umożliwia tworzenie aplikacji internetowych od podstaw. Czy może być łatwiej zdefiniować metodę żądania, ścieżkę i odpowiedź?

Innymi przykładami DSL mogą być Grabie, RSpec lub Aktywny rekord. Kluczowym elementem każdego DSL jest użycie bloków.

Czas budowy

Czas zrozumieć, co kryje się pod maską i jak może wyglądać implementacja.

Załóżmy, że mamy aplikację, która przechowuje dane o różnych produktach. Chcemy rozszerzyć ją o możliwość importowania danych z pliku zdefiniowanego przez użytkownika. Ponadto plik powinien umożliwiać dynamiczne obliczanie wartości w razie potrzeby. Aby to osiągnąć, decydujemy się na stworzenie DSL.

Prosty produkt Reprezentacja może mieć następujące atrybuty (product.rb):

 class Product
   attr_accessor :name, :description, :price
 end

Zamiast korzystać z prawdziwej bazy danych, będziemy po prostu symulować jej działanie (fake_products_database.rb):

 class FakeProductsDatabase
   def self.store(product)
     puts [product.name, product.description, product.price].join(' - ')
   end
 end

Teraz stworzymy klasę, która będzie odpowiedzialna za odczyt i obsługę pliku zawierającego dane produktów (dsl/data_importer.rb):

moduł Dsl
klasa DataImporter
moduł Składnia
def add_product(&block)
FakeProductsDatabase.store product(&block)
end

  private

  def product(&block)
    ProductBuilder.new.tap { |b| b.instance_eval(&block) }.product
  end
end

include Składnia

def self.import_data(file_path)
  new.instance_eval File.read(file_path)
end

end
end
```

Klasa posiada metodę o nazwie import_data która oczekuje ścieżki pliku jako argumentu. Plik jest odczytywany, a wynik jest przekazywany do funkcji instance_eval która jest wywoływana na instancji klasy. Co ona robi? Ocenia ciąg znaków jako kod Ruby w kontekście instancji. Oznacza to. jaźń będzie instancją DataImporter class. Dzięki temu jesteśmy w stanie zdefiniować pożądaną składnię / słowa kluczowe (dla lepszej czytelności składnia jest zdefiniowana jako moduł). Kiedy add_product metoda jest wywoływana, blok podany dla metody jest obliczany przez ProductBuilder instancja, która buduje Produkt instancja. ProductBuilder została opisana poniżej (dsl/product_builder.rb):

moduł Dsl
class ProductBuilder
ATTRIBUTES = %i[nazwa opis cena].freeze

attr_reader :product

def initialize
  @product = Product.new
end

ATTRIBUTES.each do |attribute|
  define_method(attribute) do |arg = nil, &block|
    value = block.is_a?(Proc) ? block.call : arg
    product.public_send("#{atrybut}=", wartość)
  end
end

end
end
```

Klasa definiuje składnię dozwoloną w ramach add_product block. Z odrobiną metaprogramowania dodaje metody, które przypisują wartości do atrybutów produktu. Metody te obsługują również przekazywanie bloku zamiast bezpośredniej wartości, dzięki czemu wartość może być obliczana w czasie wykonywania. Używając czytnika atrybutów, jesteśmy w stanie uzyskać zbudowany produkt na końcu.

Teraz dodajmy skrypt importu (import_job.rb):

requirelative 'dsl/dataimporter'
requirerelative 'dsl/productbuilder'
requirelative 'fakeproductsdatabase'
requirerelative "product

Dsl::DataImporter.import_data(ARGV[0])
```

I wreszcie - przy użyciu naszego DSL - plik z danymi produktów (dataset.rb):

``ruby
add_product do
name 'Ładowarka'
description 'Life saving'
cena 19.99
end

add_product do
name "Wrak samochodu
description { "Wrak samochodu w #{Time.now.strftime('%F %T')}" }
price 0.01
end

add_product do
name 'Lockpick'
description "Drzwi nie będą się zamykać
cena 7.50
end
```

Aby zaimportować dane, wystarczy wykonać jedno polecenie:

 ruby import_job.rb dataset.rb

Rezultatem jest.

 Ładowarka - ratowanie życia - 19,99
 Wrak samochodu - rozbity o 2018-12-09 09:47:42 - 0,01
 Lockpick - Drzwi nie będą się zamykać - 7.5

..sukces!

Wnioski

Patrząc na wszystkie powyższe przykłady, nietrudno zauważyć możliwości oferowane przez DSL. DSL pozwala uprościć niektóre rutynowe operacje, ukrywając całą wymaganą logikę i udostępniając użytkownikowi tylko najważniejsze słowa kluczowe. Pozwala to uzyskać wyższy poziom abstrakcji i oferuje elastyczne możliwości użytkowania (co jest szczególnie cenne pod względem możliwości ponownego wykorzystania). Z drugiej strony, dodanie DSL do swojego oprogramowania projekt powinna być zawsze dobrze przemyślana - implementacja wykorzystująca metaprogramowanie jest zdecydowanie trudniejsza do zrozumienia i utrzymania. Ponadto wymaga solidnego zestawu testów ze względu na swoją dynamikę. Dokumentowanie DSL ułatwia jego zrozumienie, więc zdecydowanie warto to robić. Choć implementacja własnego DSL może być satysfakcjonująca, warto pamiętać, że musi się opłacać.

Zainteresował Cię ten temat? Jeśli tak, daj nam znać - opowiemy Ci o DSL, które niedawno stworzyliśmy, aby spełnić wymagania w jednym z naszych projektów.

Powiązane artykuły

Software Development

Tworzenie przyszłościowych aplikacji internetowych: spostrzeżenia zespołu ekspertów The Codest

Odkryj, w jaki sposób The Codest wyróżnia się w tworzeniu skalowalnych, interaktywnych aplikacji internetowych przy użyciu najnowocześniejszych technologii, zapewniając płynne doświadczenia użytkowników na wszystkich platformach. Dowiedz się, w jaki sposób nasza wiedza napędza transformację cyfrową i biznes...

THEECODEST
Software Development

10 najlepszych firm tworzących oprogramowanie na Łotwie

Dowiedz się więcej o najlepszych łotewskich firmach programistycznych i ich innowacyjnych rozwiązaniach w naszym najnowszym artykule. Odkryj, w jaki sposób ci liderzy technologiczni mogą pomóc w rozwoju Twojej firmy.

thecodest
Rozwiązania dla przedsiębiorstw i scaleupów

Podstawy tworzenia oprogramowania Java: Przewodnik po skutecznym outsourcingu

Zapoznaj się z tym niezbędnym przewodnikiem na temat skutecznego tworzenia oprogramowania Java outsourcing, aby zwiększyć wydajność, uzyskać dostęp do wiedzy specjalistycznej i osiągnąć sukces projektu z The Codest.

thecodest
Software Development

Kompletny przewodnik po outsourcingu w Polsce

Wzrost liczby outsourcing w Polsce jest napędzany przez postęp gospodarczy, edukacyjny i technologiczny, sprzyjający rozwojowi IT i przyjazny klimat dla biznesu.

TheCodest
Rozwiązania dla przedsiębiorstw i scaleupów

Kompletny przewodnik po narzędziach i technikach audytu IT

Audyty IT zapewniają bezpieczne, wydajne i zgodne z przepisami systemy. Dowiedz się więcej o ich znaczeniu, czytając cały artykuł.

The Codest
Jakub Jakubowicz CTO & Współzałożyciel

Subskrybuj naszą bazę wiedzy i bądź na bieżąco!

    O nas

    The Codest - Międzynarodowa firma programistyczna z centrami technologicznymi w Polsce.

    Wielka Brytania - siedziba główna

    • Office 303B, 182-184 High Street North E6 2JA
      Londyn, Anglia

    Polska - lokalne centra technologiczne

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polska

      The Codest

    • Strona główna
    • O nas
    • Nasze Usługi
    • Case Studies
    • Nasze Know How
    • Kariera
    • Słownik

      Nasze Usługi

    • Konsultacje IT
    • Software Development
    • Backend Development
    • Frontend Development
    • Zespoły IT
    • Backend Dev
    • Inżynierowie rozwiązań chmurowych
    • Inżynierowie danych
    • Inne
    • Inżynierowie QA

      Raporty

    • Fakty i mity na temat współpracy z zewnętrznym partnerem programistycznym
    • Z USA do Europy: Dlaczego amerykańskie startupy decydują się na relokację do Europy?
    • Porównanie centrów rozwoju Tech Offshore: Tech Offshore Europa (Polska), ASEAN (Filipiny), Eurazja (Turcja)
    • Jakie są największe wyzwania CTO i CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Warunki korzystania z witryny

    Copyright © 2025 by The Codest. Wszelkie prawa zastrzeżone.

    pl_PLPolish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek pl_PLPolish