Going through a tutorial using modules (namespaces). I receive the following error:
blog.rb:25:in `insert_random_comment': undefined method `<<' for
#<Blog::Comment:0x007f1370368be0> (NoMethodError)
from modules.rb:13:in `<main>'
In the insert_random_comment I puts the class and methods. The class is Blog::Comment and there is no method shown for <<. So it seems I am expecting the instance variable @comment to be a list of objects but it is a single object. Would I be correct in saying that when instantiating the Blog post object I should initialize the comment with a list with contents a single blog comment?
module.rb
post = Blog::Post.new author: "Stevie G",
title: "A title",
body: "A body",
comments: Blog::Comment.new( user: "Jeffrey Way",
body: "A Comment")
post.insert_random_comment
blog.rb
module Blog
class Post
attr_reader :author, :title, :body, :comments
def initialize options
@author = options[:author]
@title = options[:title]
@body = options[:body]
@comments = options[:comments] || []
end
#*splat (only 1 splat in method signature)
#first param, *comments
# insert_comments first, second, *thirds, options, &block
def insert_comment first, second, *thirds, options, &block
comments.each { |c| @comments << c }
end
def insert_random_comment
p @comments.class
p @comments.methods
@comments << Comment.new(user: "jose Mota", body: "A body")
end
end
class Comment
attr_reader :user, :body
def initialize options
@user = options[:user]
@body = options[:body]
end
end
end
Base on your module.rb, you will assign Post.comments as an Comment object when you initialize a Post object.
post = Blog::Post.new author: "Stevie G",
title: "A title",
body: "A body",
comments: Blog::Comment.new( user: "Jeffrey Way",
body: "A Comment") #This is an object of Comment
So you could:
post = Blog::Post.new author: "Stevie G",
title: "A title",
body: "A body",
comments: [Blog::Comment.new( user: "Jeffrey Way",
body: "A Comment")] #This is an Array of Comments
When you are dealing with array, but expecting the single value may occur as an input, you might want to use ruby magick:
value = *[arg]
will hold an array, despite whether arg is an array or not:
arg = [1,2,3]
value = *[arg]
# => [
# [0] [
# [0] 1,
# [1] 2,
# [2] 3
# ]
# ]
arg = 1
value = *[arg]
# => [
# [0] [
# [0] 1
# ]
# ]
So, in your case you might want to initialize an object with either single comment or with an array:
@comments = [*options[:comments]]
Would do the trick. The problem was actially that you passed the single Comment
object in call to Blog::Post.new
(4th argument.)
UPD: Thanks to @PatriceGahide, handling of nil
was done erroneously.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.