A question on singleton methods

M

mike leonard

Hello,

I have a hash full of objects, like so:

a_hash = { :a => "alpha", :b => "beta" }

I don't I need to define a singleton method for one of the items in
the class. I thought I could do:

def a_hash.fetch:)a).to_s
"ALPHA"
end

But all this gets me is a big fat error:

t.rb:2: syntax error, unexpected tSYMBEG, expecting ')'
def a_hash.fetch:)a).to_s
^

This is just a minimal example. In real life, the objects in the hash
have been generated programatically, so I don't have variable
references for them -- just the keys.

Is it possible that there is a way around this error? If not, is there
another way to do what I'm trying to do? I'm pretty new to this, so
apologies in advance if it is an obvious mistake.

Thank you,

Mike Leonard
 
A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

Hi Mike,

def a_hash.fetch:)a).to_s
"ALPHA"
end

The problem here is that you can't involve a method call/dispatch (or two)
in the method definition. "a_hash.fetch:)a).to_s" has to make at least one
method call (a_hash.fetch:)a)), and then one defines the method on the
resulting object. Method definitions don't work this way (they need to be
resolvable in the current context, I believe). But there's a way to get
there:
a ={:a => "q"} => {:a=>"q"}
b = a[:a] => "q"
a[:a].object_id => -606856898
b.object_id => -606856898
def b.some_method
puts "Hi."
end => nil
b.some_method
Hi.
=> nil
Hi.
=> nil
By the by, I'm not sure redefining a String's #to_s will have any effect. It
sounds strange - perhaps you're better off building a class for those
objects and defining to_s on that?

Cheers,
Arlen
 
S

Sean O'Halpin

Hello,

I have a hash full of objects, like so:

a_hash = { :a => "alpha", :b => "beta" }

I don't I need to define a singleton method for one of the items in
the class. I thought I could do:

def a_hash.fetch:)a).to_s
"ALPHA"
end

But all this gets me is a big fat error:

t.rb:2: syntax error, unexpected tSYMBEG, expecting ')'
def a_hash.fetch:)a).to_s
^

This is just a minimal example. In real life, the objects in the hash
have been generated programatically, so I don't have variable
references for them -- just the keys.

Is it possible that there is a way around this error? If not, is there
another way to do what I'm trying to do? I'm pretty new to this, so
apologies in advance if it is an obvious mistake.

Thank you,

Mike Leonard
You could try this:

a_hash = { :a => "alpha", :b => "beta" }

def (a_hash[:a]).to_s
"ALPHA"
end

a_hash.each do |key, value|
puts "#{key} = #{value.to_s}"
end
__END__
a = ALPHA
b = beta

Regards,
Sean
 
D

Daniel Brumbaugh Keeney

Congratulations Sean O'Halpin, you beat me to send button.
By the by, I'm not sure redefining a String's #to_s will have any effect. It
sounds strange - perhaps you're better off building a class for those
objects and defining to_s on that?

I have no idea what the possible purpose of redefining String#to_s is.
However, I think this brings to mind an interesting idea. As part of
Ruby's duck typing initiative, many methods call to_str on objects
they expect to be strings. Having String#to_str return something other
than self could produce some extremely confusing results.

Daniel Brumbaugh Keeney
 
J

Jeff Swope

[Note: parts of this message were removed to make it a legal post.]

unsubscribe
 
M

mike leonard

By the by, I'm not sure redefining a String's #to_s will have any effect. It
sounds strange - perhaps you're better off building a class for those
objects and defining to_s on that?

Agreed. I'm really wanting to redefine #to_s for a String; it was just
the first method that I thought of when I was typing up a minimal
example of what I was trying to do. The important bit was the thing
with the singleton method. Many thanks for your help.

--Mike
 
M

mike leonard

Agreed. I'm really wanting to redefine #to_s for a String; it was just
the first method that I thought of when I was typing up a minimal
example of what I was trying to do. The important bit was the thing
with the singleton method. Many thanks for your help.

--Mike

Sorry, that should read I'm *not* really wanting to redefine #to_s for
a String.
 
7

7stud --

mike said:
Hello,

I have a hash full of objects, like so:

a_hash = { :a => "alpha", :b => "beta" }

I don't I need to define a singleton method for one of the items in
the class. I thought I could do:

def a_hash.fetch:)a).to_s
"ALPHA"
end

a_hash = { :a => "alpha", :b => "beta" }

val = a_hash.fetch:)a)
puts val.class #String

$ri String#to_s

------------------------------------------------------------ String#to_s
str.to_s => str
str.to_str => str
------------------------------------------------------------------------
Returns the receiver.


And you don't define methods like this:

def "sayhi"
puts 'hi'
end

You define them like this:

def sayhi
puts 'hi'
end

A method name is not a string.
 
A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

Hi,

A method name is not a string.

I think you're a bit off the mark. He's redefining an existing method with a
new singleton one.
=> Hash

$ ri Hash#length
------------------------------------------------------------ Hash#length
hsh.length => fixnum
hsh.size => fixnum
------------------------------------------------------------------------


Yet:

A method name is not a fixnum, either. He's not trying to define a method
called 'alpha', it was changing the definition of to_s.

Arlen
 
S

Sebastian Hungerecker

mike said:
=A0 =A0 def a_hash.fetch:)a).to_s
=A0 =A0 =A0 =A0 "ALPHA"
=A0 =A0 end

This doesn't work because ruby thinks you want to define a_hash.fetch and i=
s=20
then confused by the symbol in the parameter list. This however will work:

def (a_hash.fetch:)a)).to_s
"ALPHA"
end


HTH,
Sebastian
=2D-=20
Jabber: (e-mail address removed)
ICQ: 205544826
 
M

mike leonard

This doesn't work because ruby thinks you want to define a_hash.fetch and is
then confused by the symbol in the parameter list. This however will work:

def (a_hash.fetch:)a)).to_s
  "ALPHA"
end

HTH,
Sebastian

That got it. Thanks to everyone who chimed in to clear that up for me.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top