[Q] case based on object class

G

George Moschovitis

Hello everyone,

I wonder if there is a more elegant/efficient way to rewrite
the case structure in the following code snippet:

def myfunc(obj)
case obj.class.name
when Fixnum.name
puts :Fixnum
when Float.name
puts :Float
...
default
puts :Object
end
end

thanks in advance,

George Moschovitis


--
www.navel.gr | tel: +30 2106898050 | fax: +30 2106898437

Navel does not accept liability for any errors, viruses or omissions in
the contents of this message. The full corporate policy is available on
our site.

have fun: www.joy.gr
 
M

Michael Neumann

George said:
Hello everyone,

I wonder if there is a more elegant/efficient way to rewrite
the case structure in the following code snippet:

def myfunc(obj)
case obj.class.name
when Fixnum.name
puts :Fixnum
when Float.name
puts :Float
...
default
puts :Object
end
end

case obj
when Fixnum
puts obj.class.to_s.to_sym
when Float
...
else
puts :Object
end


Regards,

Michael
 
H

Hal Fulton

George said:
Hello everyone,

I wonder if there is a more elegant/efficient way to rewrite
the case structure in the following code snippet:

Certainly... see below.
def myfunc(obj)
case obj
when Fixnum
puts :Fixnum
when Float
puts :Float
...
default
puts :Object
end
end

This works because case invokes ===, which takes a minute
or three to understand. :)


Hal

PS - In my Mozilla, your font is microscopic. :0


H
 
G

George Moschovitis

This works because case invokes ===, which takes a minute
or three to understand. :)

Thank you Hal and Michael!

Ruby can be VERY surprising after all. After the initial shock it
feels natural though.

-g.

--
www.navel.gr | tel: +30 2106898050 | fax: +30 2106898437

Navel does not accept liability for any errors, viruses or omissions in
the contents of this message. The full corporate policy is available on
our site.

have fun: www.joy.gr
 
G

George Moschovitis

Hmm my example was wrong, what I wanted to write is:

def myfunc(klass)
case klass.name
when Fixnum.name
puts :Fixnum
when Float.name
puts :Float
...
default
puts :Object
end
end

myfunc(obj.class)

Now this === doesnt work :( I am sure the solution is obvious,
but I would appreciate some help.

regards,
George Moschovitis


--
www.navel.gr | tel: +30 2106898050 | fax: +30 2106898437

Navel does not accept liability for any errors, viruses or omissions in
the contents of this message. The full corporate policy is available on
our site.

have fun: www.joy.gr
 
H

Hal Fulton

George said:
Hmm my example was wrong, what I wanted to write is:

def myfunc(klass)
case klass.name
when Fixnum.name
puts :Fixnum
when Float.name
puts :Float
...
default
puts :Object
end
end

myfunc(obj.class)

Now this === doesnt work :( I am sure the solution is obvious,
but I would appreciate some help.

I am not sure what you want to do... do you want to separate these
things by class and print out the corresponding symbol?

Anyhow, I tried your code and it worked fine for me. I substituted
4 for obj and commented the ... of course.

What's the problem about?


Hal
 
H

Hal Fulton

Hal said:
Anyhow, I tried your code and it worked fine for me. I substituted
4 for obj and commented the ... of course.

Also, what's this 'default' thing? I'm surprised it didn't give a
syntax error... 'else' is the thing.

I guess it's interpreting that as a method call but you're never
reaching it.


Hal
 
G

George Moschovitis

I am not sure what you want to do... do you want to separate these
things by class and print out the corresponding symbol?

i want to execute different code depending on the klass (Class) object
given to the method.
Anyhow, I tried your code and it worked fine for me. I substituted
4 for obj and commented the ... of course.

the code works, I am wondering if there is a more elegant/efficient
way to write it.

-g.

--
www.navel.gr | tel: +30 2106898050 | fax: +30 2106898437

Navel does not accept liability for any errors, viruses or omissions in
the contents of this message. The full corporate policy is available on
our site.

have fun: www.joy.gr
 
G

George Moschovitis

Also, what's this 'default' thing? I'm surprised it didn't give a

hmm that was an error, I thought I was writing C or something.
it was pseudocode anyway, just to illustrate my question...

-g.

--
www.navel.gr | tel: +30 2106898050 | fax: +30 2106898437

Navel does not accept liability for any errors, viruses or omissions in
the contents of this message. The full corporate policy is available on
our site.

have fun: www.joy.gr
 
H

Hal Fulton

George said:
the code works, I am wondering if there is a more elegant/efficient
way to write it.

Well, I'd wonder why you're testing the class instead of the
object.

def myfunc(obj)
case obj
when Fixnum
# ...
when Float
# ...
else
# ...
end
end


myfunc(some_obj)


This seems better to me...


Hal
 
T

trans. (T. Onoma)

On Monday 11 October 2004 06:04 am, George Moschovitis wrote:| def myfunc(klass)|          case klass.name|                  when Fixnum.name|                          puts :Fixnum|                  when Float.name|                          puts :Float|                  ...|                  default|                          puts :Object|          end| end
This doesn't work?
def myfunc(klass)     case klass             when Fixnum                  puts :Fixnum              when Float                 puts :Float              ...             default                 puts :Object          end end

BTW the method being used by case in the above is Class#===, to be more exact it is calling Fixnum#=== and Float#===
T.
 
R

Robert Klemme

George Moschovitis said:
i want to execute different code depending on the klass (Class) object
given to the method.


the code works, I am wondering if there is a more elegant/efficient
way to write it.

The OO way is to use a mapping IMHO:

ACTION_MAPPING = {
Fixnum => lambda { puts "Fixnum" },
Float => lambda { puts "Float" },
String => lambda { puts "String" },
}

def myfunc(klass)
code = ACTION_MAPPING[klass]
raise ArgumentError, "Klass not found: #{klass}" unless code
code.call
end

You can even define a block for the error as default effectively rendering
the method a one liner like this:

ACTION_MAPPING = Hash.new( lambda { raise ArgumentError, "Klass not
found" } ).update(
Fixnum => lambda { puts "Fixnum" },
Float => lambda { puts "Float" },
String => lambda { puts "String" }
)

def myfunc(klass) ACTION_MAPPING[klass].call end

Kind regards

robert
 
R

Robert Klemme

Robert Klemme said:
The OO way is to use a mapping IMHO:

I forgot to mention that this is also more efficient if you have many
classes.
ACTION_MAPPING = {
Fixnum => lambda { puts "Fixnum" },
Float => lambda { puts "Float" },
String => lambda { puts "String" },
}

def myfunc(klass)
code = ACTION_MAPPING[klass]
raise ArgumentError, "Klass not found: #{klass}" unless code
code.call
end

You can even define a block for the error as default effectively rendering
the method a one liner like this:

ACTION_MAPPING = Hash.new( lambda { raise ArgumentError, "Klass not
found" } ).update(
Fixnum => lambda { puts "Fixnum" },
Float => lambda { puts "Float" },
String => lambda { puts "String" }
)

def myfunc(klass) ACTION_MAPPING[klass].call end

And then there is also the option to define those methods as singleton
methods of the classes although I recommend to do this *only* if the
functionality is general enough and has to do with the class more than
with your app.

Kind regards

robert
 

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,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top