1

Looking through the sourcecode of the redis-store RubyGem, I stumbled upon this syntax I hadn't seen before:

class Foo < self # ... end 

My Google-Fu apparently isn't powerful enough, because I've been able to find nothing that describes what this does.

What I'm guessing this does, is somehow reopening Foo, extending it with itself as superclass, thereby making it possible to override methods that can call the original definition as super. Am I close?

2
  • 1
    Yes, you are close! Commented Nov 11, 2019 at 13:42
  • In the linked code, self refers to Redis, so class Store < self is equivalent to class Store < Redis. Commented Nov 12, 2019 at 8:38

2 Answers 2

6
class Foo < Bar end 

Is how you tell Ruby that Foo inherits from Bar.

Within a class definition, self refers to the class itself:

# prints Foo class Foo puts self end 

So

class Foo class Bar < self end end 

Just says that Bar is nested under Foo and it inherits from it.

Sign up to request clarification or add additional context in comments.

4 Comments

Nitpick: Bar is not nested under Foo. There is no such thing as nested classes in Ruby. The constant Bar is defined inside the class Foo, but there is no relationship whatsoever between the class Bar and the class Foo. (Well, except for the fact that Bar inherits from Foo, but I am referring to the more general case of class Foo < Qux; class Bar < Garble; end end.) There are tons of Ruby tutorials that talk about nested classes, and there are tons of questions in ruby on Stack Overflow where people are confused because nested classes don't seems to work, and the …
… simple reason is that Ruby doesn't have nested classes, and we should simply never talk about them as if Ruby did have nested classes.
@JörgWMittag on the other hand, if Bar were not nested under Foo, we couldn't use self to refer to Foo ;-)
@JörgWMittag is it fair to say that the constant Bar is nested under Foo, whereas the class Bar inherits from Foo?
4

The main thing that you seem to be messing is just this: the superclass portion of a Ruby class definition is an arbitrary Ruby expression.

So, something like this is perfectly legal:

class Foo < if rand < 0.5 then Bar else Qux end end 

Obviously, this doesn't make sense, but for example, in _why the lucky stiff's brilliant little web micro framework Camping, routes are defined like this:

class Edit < R '/post/(\d+)/edit' 

and Migrations are defined like this:

class BlogInitialSchemaCreation < V 1.0 

In ActiveRecord, migrations are defined like this:

class CreateProducts < ActiveRecord::Migration[5.0] 

All of this simply uses the fact that whatever is to the right of the < in a class definition can by any arbitrary Ruby expression which is evaluated when the class definition is evaluated.

1 Comment

I think the OP was under the impression that self in class Foo < self refers to the class itself, i.e. Foo instead of Bar. (hence "with itself as superclass")

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.