2013-08-22 2 views
0

Когда я создаю новый объект, он, кажется, «значение», представление, например, находится в хэш:Что такое «значение» объекта в рубине?

h = { str: String.new("asd") } # => {:str=>"asd"} 

или просто в IRB:

String.new("asd") 
=> "asd" 

Как это сделанный? Что это за «asd»?

Когда я создаю свой собственный класс:

class A; def initalize(varl); end; end; 
a = A.new("asd") 
=> #<A:0x007fab7c2fe250> 

Что такое, что "#"? То, что я хочу, является объектом внутри хеша, который, например, ведет себя как строка. Например:

hash = {str: A.new("asd")} 
hash[:str] # => "asd" 
hash[:str].my_method 

Как я могу это сделать? Я не хочу наследовать от String. Я хочу сделать это и для других типов с другими представлениями.

Update:

Что я действительно хочу сделать, это построить хэш, где ключи и значения являются «своего рода» Целые, струнных и массивам, но имеют свои собственные определенные методы:

hash = {a: MyArray.new([:x,:y]), b: MyString.new("asdasd")} 
hash[:a] # => [:x,:y] 
hash[:b] # => "asdasd" 
hash[:b].my_method 

Фактически, хэш должен быть сериализуемым для ActiveRecord.

// Edit: я узнал, что я acutally искал:

Там нет "значения" в genereal. В моем вопросе я искал поведение объекта с точки зрения некоторых методов.

Если я хочу любой общий объект вести себя «как массив», на мой взгляд, есть вещи, которые я думал: - доступ к содержимому с помощью массива [] и массив < < запись и Array.push (вход) или array.map {блок}.

И я узнал, что очень плохо просто наследовать от Array. Гораздо лучше, если вы используете переадресацию и пересылаете эти методы в атрибут этого объекта.

Например:

class Answer::Array 
    attr_accessor :value 

    extend Forwardable 

    def_delegator :@value, :inspect 
    def_delegator :@value, :to_s 
    def_delegator :@value, :[] 
    def_delegator :@value, :[]= 
    def_delegator :@value, :each 
    def_delegator :@value, :map 

    def initlialize 
    @value = [] 
    end 

    def my_method 
    some_code 
    end 
end 

Так, чтобы объект вести себя, как и любой другой «примитивного» объект, просто использовать FORWARDABLE делегировать методы для объекта значения.

ответ

0

Я считаю, что это просто называется #to_s на объекте, когда вы делаете h[:str]

Вы можете смоделировать это с вами собственный класс, выполнив:

1.9.3p392 :012 > class A 
1.9.3p392 :013?> attr_accessor :varl 
1.9.3p392 :014?> def initialize(varl) 
1.9.3p392 :015?>  self.varl = varl 
1.9.3p392 :016?> end 
1.9.3p392 :017?> def to_s 
1.9.3p392 :018?>  varl 
1.9.3p392 :019?> end 
1.9.3p392 :020?> end 
=> nil 
1.9.3p392 :021 > h = {str: A.new("asd") } 
=> {:str=>asd} 
1.9.3p392 :023 > h[:str] 
=> asd 
+0

Итак, что же знает хэш, если называть t_s или to_a или to_i? Я имею в виду: он может также представлять собой объекты, которые я хочу представить в виде массива. – roman

+0

Все имеет '# to_s', оно определено в' Object'. Поэтому всегда будет '# to_s'. –

+2

Я думаю, что '# inspect' вызывается. – Stefan

0

Что такое «ценность» объект в рубине?

Это зависит от объекта. Вы определяете его при определении класса. Что показывает irb после каждого утверждения, это не «значение» объекта. Это строковое представление результирующего объекта.

Что это "asd"?

Это результат объект .to_s, где объект является результирующим объектом вашего последнего заявления. Объект является абстрактным понятием, и для его отображения он должен быть преобразован в нечто, что вы можете видеть, что является строкой в ​​этом случае. Это irb, который преобразует объект в строку (методом to_s), чтобы вы могли ее видеть и понимать.

Что это за "#"?

Ваш новый класс не имеет собственного метода to_s, и был вызван метод to_s одного из предков. Я думаю, что это был класс модуля, который возвращает «имя класса # < : * указатель-к-объекта *>»

То, что я хочу, это объект внутри хэш, который ведет себя как струна. Как я могу это сделать?

Определите метод to_s в своем классе.

4

Строковое представление происходит от метода с именем inspect, который представляет ваш объект в строковом формате.

class A 
    def initialize(varl) 
    @varl = varl 
    end 
    def inspect 
    "An instance of A containing #{@varl.inspect}" 
    end 
end 

A.new "abc"   # => An instance of A containing "abc" 
{key: A.new("abc")} # => {:key=>An instance of A containing "abc"} 

class A 
    def inspect 
    @varl.inspect 
    end 
end 
a = A.new "abc" 
a # => "abc" 
Смежные вопросы