Skip to main content
added 631 characters in body
Source Link
Kache
  • 336
  • 1
  • 10
class Host
  classHOST_DEFN <<= self{
    defgithub: all   'github.com',
    gitlab:  @all ||= {}'gitlab.com',
 # the `Host` singletonbitbucket: is'bitbucket.org',
 an instance}

 of `Class`attr_reader :name, and:hostname

 can havedef @vars!initialize(name, hostname)
    end@name = name
    @hostname = hostname
  end

  def ssh_regexmatch?(hostnameuri)
    regexes.each_value.any? do |regex|
      regex.match?(uri)
    end
  end

  private

  def regexes
    {
      ssh:   /blahblah#ssh #{hostname}blahblah ssh/,
    end  https: /https #{hostname} https/,
    }
  end 

  class << self
    def initializehosts
      @hosts ||= HOST_DEFN.map { |name, hostname| [name, new(name, hostname)] }.to_h
    @nameend

 = name  def matching_uri(uri)
    @host_uri = URI("http://wwwhosts.#each_value.detect {hostname}" |host| host.match?(uri) }
    end
  end
```end

# usage

Host.hosts[:github]           # => #<Host:0x00007fd95c48b5d8 @hostname="github.com", @name=:github>

uri = 'https gitlab.com https'
Host.matching_uri(uri)        # => #<Host:0x00007fd95c462c00 @hostname="gitlab.com", @name=:gitlab>
class Host
  class << self
    def all
      @all ||= {} # the `Host` singleton is an instance of `Class`, and can have @vars!
    end

    def ssh_regex(hostname)
      /blahblah#{hostname}blahblah/
    end
  end

  def initialize(name, hostname)
    @name = name
    @host_uri = URI("http://www.#{hostname}")
  end
end
```
class Host
  HOST_DEFN = {
    github:    'github.com',
    gitlab:    'gitlab.com',
    bitbucket: 'bitbucket.org',
  }

  attr_reader :name, :hostname

  def initialize(name, hostname)
    @name = name
    @hostname = hostname
  end

  def match?(uri)
    regexes.each_value.any? do |regex|
      regex.match?(uri)
    end
  end

  private

  def regexes
    {
      ssh:   /ssh #{hostname} ssh/,
      https: /https #{hostname} https/,
    }
  end 

  class << self
    def hosts
      @hosts ||= HOST_DEFN.map { |name, hostname| [name, new(name, hostname)] }.to_h
    end

    def matching_uri(uri)
      hosts.each_value.detect { |host| host.match?(uri) }
    end
  end
end

# usage

Host.hosts[:github]           # => #<Host:0x00007fd95c48b5d8 @hostname="github.com", @name=:github>

uri = 'https gitlab.com https'
Host.matching_uri(uri)        # => #<Host:0x00007fd95c462c00 @hostname="gitlab.com", @name=:gitlab>
Source Link
Kache
  • 336
  • 1
  • 10

Ruby does not have an import system like python, so variables and methods at the top level like REPO_TYPES and temp_dir are effectively global variables and methods.

Use modules to aggressively namespace, even for your main, especially when a small script begins to span more than one file:

module Degit
  def self.main # define singleton method
  end
end

Degit.main # call singleton method

This is also true for methods as well. def self.main in the example defines a singleton method on Degit itself. (Degit is a singleton in the sense that it will be the only instance of Module named "Degit", and main is a method it will now have).

Ruby classes operate in the same way:

class Foo
  class << self # opens singleton context
    def foo # also defines a singleton method
    end
  end
end

On another note, I feel like RepoType should either be:

  • completely removed and its responsibilities handled by Repo

Or

  • named Host and be more cohesive by owning variables and methods REPO_TYPE and find_repo_type within it, along with the regex definitions associated with each Host

Here's an example combining what I've outlined above:

class Host
  class << self
    def all
      @all ||= {} # the `Host` singleton is an instance of `Class`, and can have @vars!
    end

    def ssh_regex(hostname)
      /blahblah#{hostname}blahblah/
    end
  end

  def initialize(name, hostname)
    @name = name
    @host_uri = URI("http://www.#{hostname}")
  end
end
```