A course on ruby asks to write a Title class, which is initialized with a string. It has one method fix, which should return a title-cased version of the string. Here is what I have for my code.
class Title
attr_reader :string
def initialize(string)
#string = string
end
def fix
not_capitalized = %w{a and the of}
word_array = string.downcase.split(" ")
title_array = []
word_array.each_with_index do |word, index|
if index == 0 || !not_captialized.include?(word)
title_array << word.capitalize
else
title_array << word
end
end
title_array.join(" ")
end
end
I keep getting a NameError undefined local variable or method `not_captialized'. What am I doing wrong?
You have a typo in your variables.
The first one is not_capitalized
The second one is not_captialized
Just rename the second one and it should work
i.e. if index == 0 || !not_capitalized.include?(word)
Just as the error message says. You never defined a local variable or method not_captialized, but are trying to use it.
Related
I am learning ruby and getting this error
My code:
class New_class
hash{}
File.readlines('file.txt').each do |line|
if (line =~ /^(\w+)=>(.*)/)
hash[$1] =$2
end
end
def check
a='2345'
value = hash.fetch{a,''}
if (value == '')
puts 'Error no value found'
else
puts value
end
end
end
var=New_class.new
var.check
Error :undefined method 'fetch'
Here I want hash to run one time and store all the key/value so that I can use the hash in multiple methods and check for values. Anyone know how to fix this error or any better way to do?
The hash variable is out of scope. You can make it global by changing it to $hash.
Also fetch uses round brackets not curly brackets.
class New_class
$hash = {}
File.readlines('file.txt').each do |line|
if (line =~ /^(\w+)=>(.*)/)
$hash[$1] =$2
end
end
def check
a='2345'
value = $hash.fetch(a,'')
if (value == '')
puts 'Error no value found'
else
puts value
end
end
end
Undefined method for nil:Nilclass
In a class, a method counts the number of words in a paragraph.An error occurs when a method is called(1). I can’t understand how to pass the argument methods using send.
If I remove the class and put the def calc_1(paragraph) method into the loop, then everything works, I start calling the select method. It turns out he does not see my books variable with text, when there is a class.
#books = "You can use this knowledge to create small tools that might help."
class Filecalculation
def select
loop do
puts "# Will we search : сounting words in text File(1)".cyan
print "\n>>>>>> "
input = gets.chomp
search_method = "calc_#{input}".to_sym
if (respond_to?(search_method))
contents = send(search_method, #books)
end
end
end
def calc_1 paragraph
word_count = paragraph.split.length
puts "#{word_count} words"
end
end
Filecalculation.new.select
If replaced by search_method = "calc_#{input}".to_sym also works.
Helped add def initialize #books end.
Instead of contents = send (search_method, #books) you can use send (search_method, #books).
require "colorize"
class Filecalculation
def initialize
#books = "You can use this knowledge to create small tools that might help you."
end
def calc_1 paragraph
word_count = paragraph.strip.squeeze(' ').count(' ') + 1
puts "#{word_count} words"
end
def select
loop do
puts "# Will we search : Calculation_lines paragraph(1)".cyan
print "\n>>>>>> ".yellow
input = gets.chomp
search_method = "calc_#{input}" #.to_sym
if (respond_to?(search_method))
contents = send(search_method, #books)
else
puts "exit "
exit
end
end
end
end
Filecalculation.new.select
I'm starting to learn metaprogramming in Ruby and (I think) I'm understanding how to add instance methods and variables, but only if passed in one at a time. For example, test.new_value = true. I'm wondering how to add an extra depth to my command with two dots test.like.this. For example:
class StackOverflow
def initialize(name)
#name = name
end
def method_missing(argument, *args)
argument = argument.to_s
if argument =~ /failing/
puts 'FOUND FAILING'
puts argument
puts args[0]
return
end
if argument =~ /this_test_is/
puts 'FOUND THIS TEST IS'
puts argument
puts args[0]
return
end
if argument =~ /this_works=/
instance_variable_set("##{argument.to_s.chop}", args[0])
return
else
return instance_variable_get("##{argument}").to_s
end
end
end
test = StackOverflow.new("post")
test.this_works = true
puts "IT WORKED: " + test.this_works
test.this_test_is.failing
gives me the following output:
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
IT WORKED: true
FOUND THIS TEST IS
this_test_is
undefined method `failing' for nil:NilClass
(repl):44:in `<main>'
What I'm looking to do is treat this as a variable and value pair. I'd like to know how to do both of these scenarios:
A: Recognise this_test_is and treat it as a variable to have it store the string (or symbol is fine) failing.
B: Recognise failing as the variable and if I see this_test_is then set failing to true, as opposed to false if I find this_test_is_not.
Thank you in advance!
You need to add some kind of recursion :
class StackOverflow
def initialize(name)
#name = name
end
def method_missing(argument, *args)
argument = argument.to_s
if argument =~ /failing/
puts 'FOUND FAILING'
puts argument
puts args[0]
return
end
if argument =~ /this_test_is/
puts 'FOUND THIS TEST IS'
puts argument
puts args[0]
return StackOverflow.new("this_test_is")
end
if argument =~ /this_works=/
instance_variable_set("##{argument.to_s.chop}", args[0])
return
else
return instance_variable_get("##{argument}").to_s
end
end
end
test = StackOverflow.new("post")
test.this_works = true
puts "IT WORKED: " + test.this_works
test.this_test_is.failing
prints this :
IT WORKED: true
FOUND THIS TEST IS
this_test_is
FOUND FAILING
failing
I am new to Ruby and I got a question: is the nil checking necessary in following code? would you please explain a little bit? Thank you in advance!!if you think this is too easy to answer, would you please tell me the document( or link) that I need check to solve my doubts?
this is the original question:
within the say_hi method, the author checks if the instance variable #names is nil. Why is this check done? Is the check really needed in the MegaGreeter class as it is written? Why or Why not?
class MegaGreeter
attr_accessor :names
# Create the object
def initialize(names = "World")
#names = names
end
# Say hi to everybody
def say_hi
if #names.nil?
puts "..."
elsif #names.respond_to?("each")
# #names is a list of some kind, iterate!
#names.each do |name|
puts "Hello #{name}!"
end
else
puts "Hello #{#names}!"
end
end
# Say bye to everybody
def say_bye
if #names.nil?
puts "..."
elsif #names.respond_to?("join")
# Join the list elements with commas
puts "Goodbye #{#names.join(", ")}. Come back soon!"
else
puts "Goodbye #{#names}. Come back soon!"
end
end
end
if __FILE__ == $0
mg = MegaGreeter.new
mg.say_hi
mg.say_bye
# Change name to be "Zeke"
mg.names = "Zeke"
mg.say_hi
mg.say_bye
# Change the name to an array of names
mg.names = ["Albert", "Brenda", "Charles",
"Dave", "Engelbert"]
mg.say_hi
mg.say_bye
# Change to nil
mg.names = nil
mg.say_hi
mg.say_bye
end
The way the initializer is set up, #names should never be nil because of the default value of 'World' being assigned if nothing is provided.
The problem is the public attr_accessor in the MegaGreeter class, which you can read about this method here. It creates a setter method on the #names instance variable, meaning it can be changed to anything, including nil.
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.