def self.grab
article = self.article_names
links = self.article_links
body = self.article_body
articles = {}
articles[:title] = article
articles[:url] = links
articles[:body] = body
art = Ello::Hello.new
art(articles)
end
When I run this with
class Ello::Hello
attr_accessor :url, :article, :body,
##all = []
def initialize(hash)
#article = hash["title"]
#body = hash["body"]
#url = hash["url"]
##all << self
end
def self.all
##all
end
end
I get wrong number of arguments error? I know that usually when it says wrong number it means that it's not exactly reading the argument that I put in. But I feel like I did put in an argument but I'm unsure of why it's not being read.
In such cases, you should always paste the complete error message, and indicate which line in your code is affected.
Anyway, I can see that your wrote art = Ello::Hello.new (0 arguments), but the initialize method for this class expects 1 argument.
Related
When I run the command I get
all the song names and then the instances following it. How do I only
get the names?
class Song
##all = []
attr_accessor :name
def initialize(name)
#name = name
##all << self
end
def self.all
##all
end
def self.print_all_song_names
##all.each do |song|
puts song.name
end
end
end
hotline_bling = Song.new("Hotline Bling")
thriller = Song.new("Thriller")
ninety_nine_problems = Song.new("99 Problems")
thriller = Song.new("Thriller")
puts Song.print_all_song_names
Which outputs:
Hotline Bling
Thriller
99 Problems
Thriller
#<Song:0x00000000058ced30>
#<Song:0x00000000058cecb8>
#<Song:0x00000000058cebc8>
#<Song:0x00000000058ceb50>
The issue with your code is your calling puts here and there.
The code already calls puts in print_all_song_names, and after you call puts Song.print_all_song_names which roughly means call the method and print the value returned.
each returns a receiver, which means print_all_song_names returns the value of ##all class variable. Which gets printed again.
To fix it, just don’t call puts in the last line; Song.print_all_song_names already prints out everything needed.
Song.print_all_song_names # voilà
In my gem I have a class called Client that I want to operate like this:
client = Client.new
client.content_type('pages').content_type
That means I want to set a property and then expect to immediately get it back in the same chain. This is what I have so far:
class Client
attr_reader :content_type
def initialize(options = {})
#options = options
end
def content_type
#content_type
end
def content_type(type_id)
#content_type = type_id
self
end
end
Now when I try to run client.content_type('pages').content_type I get:
wrong number of arguments (given 0, expected 1) (ArgumentError)
from chaining.rb:16:in `<main>'
What am I doing wrong? How do I write this correctly?
The names of your methods are conflicting. The second method is overriding the first. Either use different names or consolidate to do both like:
class Client
attr_reader :content_type
def initialize(options = {})
#options = options
end
def content_type(type_id = nil)
if type_id
#content_type = type_id
self
else
#content_type
end
end
end
Btw, this code stinks because the returned values for this are of different type depending on how it's called. You shouldn't do it unless you have a good reason to.
I'm currently working through a set of TestFirst problems. The spec for the problem I'm working on can be found here: http://testfirst.org/live/learn_ruby/book_titles
I've tested the title method outside of the class so I know that it works, but once I place it in the class I get the following error:
1) Book title should capitalize the first letter
Failure/Error: #book.title.should == "Inferno"
ArgumentError:
wrong number of arguments (0 for 1)
Here's what I have so far:
class Book
attr_accessor :title
def initialize(title=nil)
#title = title
end
def title(title)
first_check = 0
articles = %w{a the an in and of}
words = title.split(" ")
words.each do |word|
if first_check == 0
word.capitalize!
first_check += 1
elsif !articles.include?(word)
word.capitalize!
end
end
#title = words.join(" ")
end
end
If someone could explain how the class should be formatted, it'd be greatly appreciated!
Your problem is right here:
def title(title)
Your Book#title method expects an argument but you're not giving it one in your spec:
#book.title.should == "Inferno"
# ----^^^^^ this method call needs an argument
I think you actually want a Book#title= method:
def title=(title)
# The same method body as you already have
end
Then you'll use the title accessor method that attr_accessor :title supplies and assigning a new title will use your title= method. And since you're supplying your own mutator method, you could use attr_reader instead:
class Book
attr_reader :title
def initialize(title=nil)
#title = title
end
def title=(title)
#...
end
end
Currently struggling through an rspec tutorial and would really appreciate some clarification.
Code is:
class Book
attr_reader :title
def initialize(title=nil)
#title = title = title && title.capitalize!
end
def title=(new_title = nil)
#title = new_title && new_title.each do |word|
word.capitalize!
end
end
Two questions:
Why are there two sets of #title (that is: why is it defined in both initialize and title as being set = to different things)?
Why does the title method have an = after it? The code breaks if I do not use the =.
edit: for the purposes of my rspec tutorial this is the code i finally tried that worked
class Book
attr_accessor :title
def initialize(title = nil)
#title = title
end
def title=(book_title = nil)
#title = book_title.capitalize
end
end
My initial problem was with the title= method. Finally I came upon a thread that explain what method= function was. It is necessary if you want to assign a value to something within a class method (at least that is my understanding at this point. Feel free to correct me).
I would appreciate any tips in this new code as well.
Let's analize that:
attr_reader :title
Here we are basically defining the method:
def title; #title; end
which returns the instance variable #title.
def initialize(title=nil)
#title = title = title && title.capitalize!
end
Here we are defining a 0-1 arguments constructor which can be reduced to:
def initialize(title=nil)
title && #title = title.capitalize
end
The fact is that title within the constructor is the argument variable and not the title or title= method, therefore the title= method defined later is never called here. Notice that && is used for short-circuit evaluation here.
def title=(new_title = nil)
#title = new_title && new_title.each do |word|
word.capitalize!
end
Here we actually have two syntax errors: the first one is that for Strings (which I assume is the type of a title as it appears to call String#capitalize! later) does not have the each method. Whoever wrote this probably meant String#each_char or to String#split it first instead.
The second error is that the block after the each is not closed with an end.
Now assuming this version instead:
def title=(new_title = nil)
#title = new_title && new_title.split(' ').each { |word| word.capitalize! }.join(' ')
end
the title= would just assign title to the #title variable for the same reason (short-circuit evaluation) as before and could be reduced to:
def title=(new_title = nil)
new_title && #title = new_title
end
The initialize method is called when an instance of the class is constructed. The #title = ... there sets the initial value of #title.
The title= method is called when someone subsequently sets the value of title on an instance of the class. It then adjusts the value of #title accordingly. See Ruby Accessors for a detailed explanation.
As an example:
book = Book.new # calls initialize
book.title = 'foo' # calls title=
I'm trying to build a relatively simple app in ruby. However I am unable to get my object to return anything other than 0 when puts obj.to_s is called on it. I understand the quality of the code may be poor (and wouldn't mind any hints).
Help please!
class Docpart
def Docpart.new(inputAsString,typeAsInteger)
#value = inputAsString
#type = typeAsInteger.to_i # 0 = title, 1 = text, 2 = equation (can't be done yet), 3 = table
end
def Docpart.to_s
return "Type is #{#type}, value is #{#value}"
end
end
module Tests
def Tests.test1()
filetree = Array.new(0)
filetree.push( Docpart.new("Title",0))
filetree.each{|obj| puts obj.to_s}
return filetree[0]
end
end
puts Tests.test1.to_s
gets.chomp
Because you defined class method to_s not instance one. Also writing constructor in Ruby is a little different. You need to write this that way:
class Docpart
def initialize(inputAsString,typeAsInteger)
#value = inputAsString
#type = typeAsInteger.to_i # 0 = title, 1 = text, 2 = equation (can't be done yet), 3 = table
end
def to_s
"Type is #{#type}, value is #{#value}"
end
end
module Tests
def self.test1
filetree = []
filetree << Docpart.new("Title",0)
filetree.each{ |obj| puts obj.to_s }
filetree[0]
end
end
puts Tests.test1.to_s
gets.chomp
PS Read any book about Ruby and any styleguide like Githubbers or bbatsov one.