Repository: rails/rails
File: actionpack/lib/action_dispatch/http/url.rb (Ruby)

Code before:
          add_params(path, options[:params]) if options.key?(:params)
          add_anchor(path, options[:anchor]) if options.key?(:anchor)

          path
        end

        private
          def add_params(path, params)
            params = { params: params } unless params.is_a?(Hash)
            params.reject! { |_, v| v.to_param.nil? }
            query = params.to_query
            path << "?#{query}" unless query.empty?
          end

          def add_anchor(path, anchor)
            if anchor
              path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param)}"
            end
          end

          def domain_extractor_class
            domain_extractor || DomainExtractor
          end

          def extract_domain_from(host, tld_length)
            domain_extractor_class.new(host, tld_length).domain
          end

          def extract_subdomains_from(host, tld_length)
            domain_extractor_class.new(host, tld_length).subdomains
          end

          def build_host_url(host, port, protocol, options, path)
            if match = host.match(HOST_REGEXP)
              protocol ||= match[1] unless protocol == false
              host       = match[2]
              port       = match[3] unless options.key? :port
            end

            protocol = normalize_protocol protocol
            host     = normalize_host(host, options)

            result = protocol.dup

            if options[:user] && options[:password]
              result << "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@"
            end

            result << host
            normalize_port(port, protocol) { |normalized_port|
              result << ":#{normalized_port}"

Review comment (refactor):
```suggestion
            domain_extractor.new(host, tld_length).domain
```

Code after:
        #   DomainExtractor.subdomains_from("example.com", 1)
        #   # => []
        #
        #   # Single subdomain with complex TLD
        #   DomainExtractor.subdomains_from("www.mysite.co.uk", 2)
        #   # => ["www"]
        #
        #   # Multiple levels of subdomains
        #   DomainExtractor.subdomains_from("dev.api.staging.example.com", 1)
        #   # => ["dev", "api", "staging"]
        def subdomains_from(host, tld_length)
          parts = host.split(".")
          parts[0..-(tld_length + 2)]
        end
      end

      mattr_accessor :secure_protocol, default: false
      mattr_accessor :tld_length, default: 1
      mattr_accessor :domain_extractor, default: DomainExtractor

      class << self
        # Returns the domain part of a host given the domain level.
        #
        #     # Top-level domain example
        #     extract_domain('www.example.com', 1) # => "example.com"
        #     # Second-level domain example
        #     extract_domain('dev.www.example.co.uk', 2) # => "example.co.uk"
        def extract_domain(host, tld_length)
          extract_domain_from(host, tld_length) if named_host?(host)
        end

        # Returns the subdomains of a host as an Array given the domain level.
        #
        #     # Top-level domain example
        #     extract_subdomains('www.example.com', 1) # => ["www"]
        #     # Second-level domain example
        #     extract_subdomains('dev.www.example.co.uk', 2) # => ["dev", "www"]
        def extract_subdomains(host, tld_length)
          if named_host?(host)
            extract_subdomains_from(host, tld_length)
          else
            []
          end
        end

        # Returns the subdomains of a host as a String given the domain level.
        #
        #     # Top-level domain example
        #     extract_subdomain('www.example.com', 1) # => "www"
        #     # Second-level domain example
        #     extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www"