rubocop / ruby-style-guide

A community-driven Ruby coding style guide
https://rubystyle.guide
16.46k stars 3.4k forks source link

Avoiding use of class references built via strings/`constantize` #806

Open Skipants opened 4 years ago

Skipants commented 4 years ago

The problem:

As a developer, if I am changing how a class is used or named, I would need to grep against the codebase with the name of the class. If this class is ever referenced via constantize then I will not find that reference without already knowing it's already there.

eg.

# Class definitions
class AdminUser; end
class RegularUser; end

# bad usage
user_klass = "#{admin_accessible? ? "Admin" : "Regular")}User".constantize

# good usage
user_klass =
  if admin_accessible?
    AdminUser
  else
    RegularUser
  end

The solution: I think using constantize is the issue here. I think there are cases where it needs to be used, but in general it causes the problem I outlined.

pirj commented 4 years ago

Do you think this is specific to Rails? I can transfer it to the Ruby Style Guide issue tracker for you.

Skipants commented 4 years ago

I'm not too sure. constantize is a ActiveSupport method and I think my decision to put it here was based on making a rule around the usage of that method somehow. What's your thoughts on it, @pirj ?

pirj commented 4 years ago

I mean constantize is definitely a Rails-related method, but is it about constantize or instrumenting class names?

> self.class.const_get("Obj" + "ect")
=> Object
Skipants commented 4 years ago

Makes sense. Transfer away!

bbatsov commented 4 years ago

PR welcome! :-)