3

I'm learning ruby and can't for the life of it figure out what this does:

def topic_list
  topics.map(&:name).join(",")
end

def topic_list=(names)
  if names.present?
    topics = names.split(",")
    self.topics = topics.map do |n|
      unless topic = Topic.find_by(slug: n)
        topic = Topic.create!(name: n)
      end
      topic
    end
  end
end

Why would two functions have the same name? Does the first function call the second one?

user3188544
  • 1,611
  • 13
  • 21

2 Answers2

5

topic_list is a getter and topic_list= is a setter method. No they are not the same methods.

This question Trying to learn / understand Ruby setter and getter methods will be helpful as a basic food for this concept. So Read it.

The line self.topics = topics.map... in the method topic_list=, and topics.map(&:name).join(",") line in the method topic_list smells there is one getter called topics and setter topics=. I am sure(If you tell this code works altough) about this by looking at your code.

Community
  • 1
  • 1
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • @Hopstream No it is not like that. OP took the part of the code, to understand the topic. – Arup Rakshit Jan 29 '14 at 08:23
  • How does the getter get the `:name` if it doesn't have any arguments? In this: `topics.map(&:name).join(",")` – user3188544 Jan 29 '14 at 08:30
  • 1
    @user3188544 I am sure as `self.topics=` is used in the method `topic_list=`. So there obviously exist an instance variable `@topics` and there must be exist getter `topics` and setter `topics=`. – Arup Rakshit Jan 29 '14 at 08:32
1

To clarify Arup Rakshit's answer a little more:

Ruby allows having some "weird" characters in its methods, that you would normally not see in other languages. The most notably ones are ?, ! and =.

So, you can define the methods:

def answered?()
  not @answer.nil?
end

def answer!()
  @answer = Answer.new
end

def answer()
  @answer
end

def answer=(answer)
  @answer = answer
end

For someone coming from, say, PHP, this looks strange. But really they are all different methods! I have added brackets everywhere, to clarify my point, but in Ruby, you can leave them off, so when a method does not take arguments,people generally leave them off.

def answer()
end
def answer
end

Are the same.

The last two, the answer() and answer=(), are often refered to as getters and setters. The first is often used to test something binary, like has_question? or valid?. The second is referred to as a bang method, answer!, more often used in methods that modify itself, like some_array.merge!(other_array), which modifies some_array.

Community
  • 1
  • 1
berkes
  • 26,996
  • 27
  • 115
  • 206