Reputation: 97
When I create a new object, it seems to have a "value", a representation that for example resides in a hash:
h = { str: String.new("asd") } # => {:str=>"asd"}
or just in irb:
String.new("asd")
=> "asd"
How is that done? What is this "asd"?
When I create my own class:
class A; def initalize(varl); end; end;
a = A.new("asd")
=> #<A:0x007fab7c2fe250>
What is that "#"? What I want is an object inside a hash, that, for example, behaves like a string. Like this:
hash = {str: A.new("asd")}
hash[:str] # => "asd"
hash[:str].my_method
How can I do that? I don't want to inherit from String. I want to do this for some other types with other representations too.
Update:
What i really want to do is to build a Hash where the keys and the values are "some kind of" Integers, Strings and Arrays but have my own defined methods:
hash = {a: MyArray.new([:x,:y]), b: MyString.new("asdasd")}
hash[:a] # => [:x,:y]
hash[:b] # => "asdasd"
hash[:b].my_method
In fact, the hash should be serializable for ActiveRecord.
//Edit: I found out what i acutally searched for:
There is no "value" in genereal. What i looked for in my question was the behaviour of an object in terms of some methods.
If i want any general object to behave "like an array", in my mind there were things that i thought of: - accessing contents via array[] and array << entry and array.push(entry) or array.map{block}.
And i found out that is very bad to just inherit from Array. A much better apporach is to use forwardable and and forward these methods to an attribute of that object.
For example:
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
So to let an object behave like any other "primitive" object, just use Forwardable to delegate methods to a value object.
Upvotes: 0
Views: 265
Reputation: 1208
What is the “value” of an object in ruby?
It depends on the object. You define it when you define a class. What irb shows after each statement, is not the "value" of an object. It's a string representation of the resulting object.
What is this "asd"?
It's the result of object.to_s, where object is the resulting object of your last statement. Object is an abstract concept, and in order to show it, it needs to be converted to something you can see, which is a string in this case. It's irb that converted the object to string (by to_s method) so that you can see and understand it.
What is that "#"?
Your new class doesn't have its own to_s method, and the to_s method of one of the ancestors was called. I think it was of Module class, which returns "#<class-name:*pointer-to-the-object*>"
What I want is an object inside a hash, that behaves like a string. How can I do that?
Define to_s method in your class.
Upvotes: 0
Reputation: 31756
The string representation comes from a method named inspect
, which represents your object in a string format.
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"
Upvotes: 4
Reputation: 6382
I believe it is just called #to_s
on the object when you do h[:str]
You can simulate this with you own class by doing:
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
Upvotes: 0