이해해야 하는 7가지 Ruby 표준 라이브러리

Ruby에는 Standard Library 에 유용한 것들이 많이 있습니다.

포함된 내용과 사용 방법을 배우는 것은 특히 번들러를 가져오고 Gemfile 등을 만들기 시작하고 싶지 않은 작은 스크립트를 작성할 때 매우 유용할 수 있습니다.

이 라이브러리는 강력하고 핵심 팀에서 유지 관리하며 매우 안정적이어야 하며 대부분의 Ruby 보석보다 오래 지속되어야 합니다.

1. Net/HTTP 및 open-uri



저는 제가 구축하는 대부분의 애플리케이션에 필요한 것으로 시작하고 싶었습니다. 바로 HTTP 요청을 수행하는 기능입니다.

과거에는 HTTP.rb gem을 사용하기로 선택했지만 간단한 작업의 경우 Net/http 또는 간단한 GET 요청open-uri을 배우는 것이 정말 유용합니다.

require "net/http"
require "json"

# Net/HTTP GET request
uri = URI("https://swapi.dev/api/films/1/")
resp = Net::HTTP.get(uri)
json = JSON.parse(resp)
puts json["title"] # => "A New Hope"

# Net/HTTP POST request
uri = URI("https://example.org/users")
params = {
  "name" => "Bob",
  "email" => "[email protected]",
}
res = Net::HTTP.post_form(uri, params)
puts res.body

# Net/HTTP Full form: delete/put/patch requests
uri = URI("http://example.org/some_path")

Net::HTTP.start(uri.host, uri.port) do |http|
  request = Net::HTTP::Delete.new uri
  # or request = Net::HTTP::Patch.new uri
  # or request = Net::HTTP::Put.new uri

  response = http.request(request) # Net::HTTPResponse object
  puts response.body
end


GET 요청만 필요한 경우 open-uri를 사용하면 상황이 훨씬 더 간단해집니다.

require "open-uri"
require "json"

URI.open("https://swapi.dev/api/films/1/") do |io|
  json = JSON.parse(io.read)
  puts json["title"] # => "A New Hope"
end

# or
uri = URI("https://swapi.dev/api/films/1/")
puts uri.open.read


2. CSV



관리 섹션을 만들 때 응용 프로그램의 성능을 측정하기 위해 보고서 형식을 내보내야 하는 경우가 많습니다. Ruby에는 이 기능이 내장되어 있으며 일부 데이터를 가져와서 CSV에 저장하는 것은 매우 간단합니다.

require "csv"

module CustomerExport
  module_function

  def generate(customers)
    CSV.generate do |csv|
      # Define the headers
      csv << %w[id name email country_code created_at updated_at]

      # Add a new row for each customer record
      customers.each do |customer|
        csv <<
          [
            customer.id,
            customer.name,
            customer.email,
            customer.country_code,
            customer.created_at,
            customer.updated_at
          ]
      end
    end
  end
end

CustomerExport.generate(Customer.all)


그리고 이것을 다운로드하기 위해 Rails 경로를 만들고 싶다면 ...

module Admin
  class ExportsController < AdminBaseController
    def customers
      customers = Customer.all
      respond_to do |format|
        format.csv do
          filename = "customers-#{Time.zone.now.strftime("%Y-%m-%d")}"
          filename += ".csv"
          headers["Content-Type"] ||= "text/csv"
          headers["Content-Disposition"] =
            "attachment; filename=\"#{filename}\""
          render plain: CustomerExport.generate(customers)
        end
      end
    rescue => e
      flash[:error] = "Failed to generate export: #{e.message}"
      redirect_to admin_path
    end
  end
end


CSV 구문 분석(예: 사용자로부터 CSV 파일 가져오기)도 기본 제공되며 이에 대해 자세히 알아볼 수 있습니다read the documentation.

3. SimpleDelegator



나는 SimpleDelegator을 사용하여 Stripe 특정 코드를 StripeWrappedUser 또는 이와 유사한 것으로 포장하는 것과 같은 ActiveRecord 개체에 추가 동작을 추가하는 것을 좋아합니다. 이렇게 하면 ActiveRecord 개체에 많은 메서드를 배치하는 것을 방지할 수 있지만 추가로 해당 클래스를 보강할 수 있습니다. 기능.

require "delegate"
require "digest"

class User < Struct.new(:id, :email)
end

class BillingUser < SimpleDelegator
  def billing_system_id
    Digest::SHA1.hexdigest(id.to_s + email)
  end
end

bob = User.new(1, "[email protected]")
bob = BillingUser.new(bob)
puts bob.email # => [email protected]
puts bob.billing_system_id # => 186da93f0b39990e034a80cc4b45c8ec253f2a1a


4. 구조체와 OpenStruct



Struct는 Ruby 코어에 포함되어 있으며 필요하지 않으며 두 객체 중 더 엄격하고 성능도 훨씬 뛰어납니다.

다음 두 가지 경우에 특히 유용합니다.
  • 값 개체로 데이터의 일부에 이름을 지정하면 해시가 됩니다.
  • FakeUser와 같은 가짜를 나타내기 위해 전달할 수 있는 모의 개체를 만드는 테스트에서.

  • User = Struct.new(:id, :email)
    alice = User.new(1, "[email protected]")
    puts alice.id # => 1
    puts alice.email # => [email protected]
    
    # Can also be defined with additional methods
    class User < Struct.new(:id, :email)
      def send_welcome_email
        UserMailer.welcome(self).deliver_later
      end
    end
    


    한편 OpenStruct는 훨씬 더 유연하며 API 등의 해시 또는 JSON에 대한 깔끔한 래퍼가 될 수 있습니다.

    require "ostruct"
    
    data = OpenStruct.new(id: 5, name: "Jeffrey")
    
    # New attributes can be set at runtime:
    data.email = "[email protected]"
    
    puts data.id # => 5
    puts data.name # => "Jeffrey"
    puts data.email # => "[email protected]"
    


    5. PS스토어



    PStore은 정말 간단한 키-값 데이터 저장소이며 비프로덕션 시스템에 데이터를 저장할 어딘가가 필요할 때 유용할 수 있습니다(즉, 이것은 ActiveRecord를 대체하기에 적합하지 않음).

    require "pstore"
    
    store = PStore.new("my_db.pstore")
    
    # Write some data
    store.transaction do
      store["person-1"] = { name: "Bob", email: "[email protected]" }
    end
    
    # Read some data
    store.transaction(true) do
      puts store["person-1"] # => {:name=>"Bob", :email=>"[email protected]"}
    end
    


    6. 미니테스트



    더 작은 스크립트로 작업할 때 테스트 프레임워크를 가져와서 일부 코드를 테스트 구동하는 동안 몇 가지 주장을 하는 것을 좋아합니다.

    나는 일반적으로 Rails로 작업할 때 RSpec을 선호하지만 Ruby에 포함된 Minitest 보다 설정하는 데 더 많은 노력이 필요합니다.

    Minitest의 좋은 점은 바로 Ruby입니다. 마법 같은 일이 일어나지 않고 매우 이해하기 쉽습니다.

    require "minitest/test"
    require "minitest/autorun"
    
    class APIResponse < Struct.new(:body, :error)
      def success?
        error.nil?
      end
    end
    
    class APIResponseTest < Minitest::Test
      def test_successful_responses
        resp = APIResponse.new("Well done!", nil)
        assert resp.success?
      end
    
      def test_error_responses
        resp = APIResponse.new(nil, StandardError.new("400 bad request"))
        refute resp.success?
      end
    end
    
    # Running:
    # ..
    # Finished in 0.000957s, 2089.8640 runs/s, 2089.8640 assertions/s.
    # 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
    


    7. 로거



    로거를 사용하면 스크립트를 작성할 때 많은 디버그 출력을 정리할 수 있으며 더 많거나 적은 출력을 표시하도록 로그 수준을 제어할 수 있습니다. 참고: Rails에서 Rails.logger를 사용하십시오.

    require "logger"
    
    logger = Logger.new(STDOUT)
    
    # Setting :warn will only show warning, error and fatal.
    logger.level = :warn
    
    # Can tweak log output to be less verbose
    logger.formatter = proc do |severity, datetime, progname, msg|
      "#{severity[0...1]} #{datetime.strftime('%H:%M %b %d %Y')}: #{msg}\n"
    end
    
    logger.debug("Created logger") # wont be displayed in current log level
    logger.info("Program started") # wont be displayed in current log level
    logger.warn("Nothing to do!")
    logger.error("Something really bad!")
    
    # =>
    # W 14:56 Oct 22 2021: Nothing to do!
    # E 14:56 Oct 22 2021: Something really bad!
    



    Ruby Standard Library에는 익숙해져야 할 내용이 더 많이 있지만 이 7가지가 제가 몇 번이고 다시 생각하게 되는 것입니다.

    좋은 웹페이지 즐겨찾기