2

Of course enum's don't exist in Ruby, but based on this post I've used something like the following:

class PostType
   Page = 1,
   Post = 2
end

I want to pass the value to a method and use it for a comparison. So:

initialize(post_type)
   if post_type = PostType::Page
       # do something here
   elsif post_type = PostType::Post
       # do something else here
   end
end

But this doesn't work, regardless of what I pass into the constructor of my class, it always yields the same result.

Any ideas as to why passing the "fake enum" into a method and trying to compare it won't work? Do I have to compare the value? i.e. post_type = 2 ?

Community
  • 1
  • 1
Kieran Senior
  • 17,960
  • 26
  • 94
  • 138

5 Answers5

4

you assign instead of compare

initialize(post_type) 
   if post_type == PostType::Page 
       # do something here 
   elsif post_type == PostType::Post 
       # do something else here 
   end 
end 
peter
  • 41,770
  • 5
  • 64
  • 108
  • Dang, there's me thinking Ruby syntax for comparisons were single ='s. Stupid mistake. Cheers! – Kieran Senior Apr 23 '12 at 13:27
  • 1
    If you use "ruby -w", you'd get a warning for using an assignment in a conditional expression. Better than nothing I suppose? – Romain Apr 23 '12 at 13:30
  • you'r right but i don't us the -w myself much cause my results and the real errors tend to get obfuscated by them, often it are remarks about deprecated things in gems which you don't control – peter Apr 23 '12 at 13:38
4

Besides the fact you should use Symbols, there's a syntax error, I assume you want different semantics:

if post_type = PostType::Page

should be

if post_type == PostType::Page

So your code should look like

if post_type == :page
...
Reactormonk
  • 21,472
  • 14
  • 74
  • 123
  • 1
    Because it's the ruby way. If you code in ruby, use the ruby mindset, not one where you use magic numbers. – Reactormonk Apr 23 '12 at 13:26
  • Alright, but although it's right, I see it as not rather unrelated to the original question. But ultimately I +1 based on the fact your argument boils down to "you cannot achieve the type-safety you'd get from Enums in Java (for example) in ruby. – Romain Apr 23 '12 at 13:30
  • type-safety you have in java, all the rest of the goodies in ruby 8>), i remind the time i was programming in java to lose half of my time because i had to convert vars and methods to such or so type – peter Apr 23 '12 at 13:35
  • Yes, it's unrelated. But I assume there's a slight culture of hinting people if they're about to shoot themselves in the foot. And no, it's not about type-safety. It's about embracing the style of the ruby community. If you see someone use strings as Enums in Java, you'll likely tell them they're doing it wrong as well. – Reactormonk Apr 23 '12 at 13:35
  • +1 It is _not_ unrelated. Tass answered the question, _and_ suggested a better approach. I'm actually shocked; this is the only answer that mentions `Symbol`s, which is _specifically_ designed to solve the problem of naming things. – Matheus Moreira Apr 23 '12 at 14:17
4

You're assigning instead of comparing. Using == instead of = should yield better results.

 initialize(post_type)
    if post_type == PostType::Page
        # do something here
    elsif post_type == PostType::Post
        # do something else here
    end
end
Romain
  • 12,679
  • 3
  • 41
  • 54
3

You could use a case:

case post_type
  when PostType::Page then  # Do something
  when PostType::Post then  # Do something else
  else raise 'Invalid post type'
end

Also, you really should be using Symbols for this:

case post_type
  when :page then # Do something
  when :post then # Do something else
  else raise 'Invalid post type'
end
Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
1

That's why a good habit to do this:

def initialize(post_type)
   if PostType::Page == post_type
       # do something here
   elsif PostType::Post == post_type
       # do something else here
   end
end

If you do make such a mistake, the compiler will make a warning "already initialized constant ..."

megas
  • 21,401
  • 12
  • 79
  • 130