Hayasama
Hayasama

Reputation: 21

Ruby class methods calling it twice?

class Tests
  def self.test1
    'This is the First'
  end

  def self.test2
    'This is the second'
  end
end
puts Tests.test1.test2

I keep getting an error

undefined method `test2' for "This is the First":String (NoMethodError).

I am assuming its not possible to call the second class method. However I am doing coding something which tells me that is possible. Can anyone confirm or help fix this?

Upvotes: 1

Views: 1957

Answers (4)

akuhn
akuhn

Reputation: 27813

Looks like you are trying to build a "fluent interface"

The basic idea is that when all methods on an object return self then they can be chained together without repeating the receiver. This idea has been popularized by Martin Flower in this blog post but goes all the way back to Smalltalk's ; method chaining syntax.

This is unrelated to class methods actually and works just the same way for instance methods. Here is an example that passes the chain from class to instance side

class Lorem
  def self.ipsum
    Lorem.new # passing the change from class to instance side
  end
  def dolor
    self
  end
  def sit
    self
  end
  def amet
    self
  end
end

Lorem.ipsum.dolor.sit.amet

Upvotes: 2

Andrey Deineko
Andrey Deineko

Reputation: 52367

If you return self from each method, you can chain them infinite number of times :)

Note: I've added puts to each method, because otherwise all method would do is returning self.

class Tests
  def self.test1
    puts 'This is the First'
    self
  end

  def self.test2
    puts 'This is the second'
    self
  end
end

Tests.test1.test2
#=> This is the First
#=> This is the second

Basically you perform some logic in method, and when it's done, you return the object itself, so that each chained method call gets called on the object, not on the result of previous method (when there were no self returned).

Upvotes: 2

sghosh968
sghosh968

Reputation: 601

Not quite sure why you want to chain the method calls here, you can invoke those separately.

Tests.test1
=> "This is the First"

Tests.test2
=> "This is the second"

short explanation of the error, first method test1 returns a string, which has no method test2 defined under it which results to

error undefined method `test2' for "This is the First":String (NoMethodError)

Upvotes: -1

Undo
Undo

Reputation: 25697

Not possible with those definitions; you're defining two class methods on your Tests class. This is equivalent to your code:

string = Tests.test1
# => string = "This is the First"
string.test2
# => (undefined method)

Since test2 isn't defined on the String class, you'll get the undefined method 'test2' for (...):String error.

Upvotes: 1

Related Questions