Как передать аргументы непосредственно классу без вызова нового метода? - PullRequest
1 голос
/ 05 июня 2019

В Ruby хэш может быть создан:

Hash(a: 5, b: 6)

Массив можно создать так:

Array(100)

Наборы могут быть созданы с кодом:

require 'set'
Set[1,2,3]

Итак, как я могу определить класс, который может принимать аргументы без вызова метода initialize?

Ответы [ 2 ]

4 голосов
/ 05 июня 2019

Итак, как я могу определить класс, который может принимать аргументы без вызова метода initialize?

Ты не можешь. В ваших примерах Hash и Array на самом деле являются методами.

И пример с Set использует Set :: [] , естественно. И поэтому он ничем не отличается от любого другого метода класса, который возвращает вам экземпляры этого класса. Например, User::create (или что у тебя).

0 голосов
/ 05 июня 2019

В Ruby хэш может быть создан:

Хеш (а: 5, б: 6)

Hash () на самом деле является методом модуля Kernel:

p defined?(Hash())           # => "method"
p defined?(Kernel.Hash())    # => "method"

Но без скобок, Hash, Array, String и т. Д. Все это просто классы:

defined?(Hash)     # => "constant"
defined?(Array)    # => "constant"

В Ruby 2.6.3 то же самое касается Arrays (), Complex (), Float (), Hash (), Integer (), Rational (), String () и URI () - все они являются методами .

Но Set это класс:

require 'set'

p defined?(Set)    # => "constant"
p set = Set[1,2,3] # => #<Set: {1, 2, 3}>
p set.to_a         # => [1, 2, 3]

Итак, Set [1,2,3] фактически вызывает метод [] Set. Это выглядит примерно так:

class Something
    def initialize(*a)
        @hash = {}
        a.each { |v| @hash.store(v, nil) }
    end

    def self.[](*a) new(*a) end

    define_method(:to_a) { @hash.keys }

    define_method(:inspect) { "#<#{self.class}: {#{@hash.keys.to_s[1..-2]}}>" }
    alias :to_s :inspect
end

p defined?(Something)                                   # => "constant"
p set = Something[1,2,3]                                # => #<Something: {1, 2, 3}>
p set1 = Something[[1, 2, 3], 2, 2, 3, 4, {4 => :a}, 5] # => #<Something: {[1, 2, 3], 2, 3, 4, {4=>:a}, 5}>

p set.to_a                                              # => [1, 2, 3]
p set1.to_a                                             # => [[1, 2, 3], 2, 3, 4, [4, 4], 5]

Вернуться к вопросу:

Итак, как я могу определить класс, который может принимать аргументы без вызова метод инициализации?

Не думаю, что это возможно!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...