Proper usage of 'end_with?'? - ruby

I'm attempting to gather all files in my local directory with a .xlsx file format and pull them into my AWS S3 Bucket, however, my method for doing that
attr_reader :bucket, :object_key, :input_file_path
def initialize(bucket:, object_key:, input_file_path:)
#bucket = bucket
#object_key = object_key
#input_file_path = input_file_path
end
def call
return unless input_file_path.end_with?(".xslx")
object = s3_resource.bucket(bucket).object(object_key)
object.upload_file(input_file_path)
end
returns me
[5] pry(main)> Accounting::Datev::Utils::ExcelUtil.new(bucket: nil, object_key:nil, input_file_path: nil).call
NoMethodError: undefined method `end_with?' for nil:NilClass
Am I using end_with? incorrectly?

As #razvans points out, the error message here is great.
The Error
You're initializing your object with input_file_path: nil, and then inside of call you're checking if #input_file_path (set to input_file_path in the initializer, AKA nil) ends with a string.
There is no .end_with? method on nil. That's causing the NoMethodError error.
The Solution
You could guard against nil in your end_with? call, or give it a default value in the initializer.

Related

undefined method `gsub' for nil:NilClass ruby

i am a newbie in ruby... I'm trying to convert media into a scorm package using what i found on github but i got an error while trying to run the script in the command prompt undefined method `gsub' for nil:NilClass. I guess it may be due to a defined method. any idea on how i can remove this error ?
dir = ARGV.shift.gsub(/\/+$/, '')
index = nil
media = []
Dir["#{dir}/media/*.json"].each do |file|
id = JSON.parse(File.read(file))
base = file.gsub(/\/media\/.*\.json$/, '')
index = "#{base}/index.html"
name = File.basename file
media.push [name,id]
puts "#{name}: #{id}"
end
As the error says, you are calling the method gsub on an object that is an instance of NilClass, in other words you are calling gsub on nil.
The error message tells you in which method and on which line this happens and how you got to that line of code. You will have to examine the error message to find the place in your code where you are calling gsub on an object that is nil, then you have to examine your code to find out why that object is nil instead of a String as you expect it to.

Getting undefined error in mass text app

I'm creating a app that sends mass texts using a JSON file with the numbers and names. Every time I test load the app in IRB I get the error:
NameError: undefined local variable or method `data_from_file' for main:Object
from /home/qc/tep/Coding Stuff/Ruby/text app/main.rb:14:in `contacts_from_file'
I understand what the error means, but I don't understand why I'm getting the error, here's the source code:
require 'json'
def sanatize(numbers)
"+1" + number.gsub(/^1|\D/, "")
end
def numbers_from_file
file = open('numbers.json').read
JSON.parse(file)
end
def contacts_from_file
contacts= { }
data_from_file['feed']['entry'].each do |entry|
name = entry['gsx$name']['$t']
number = entry['gsx$number']['$t']
contacts[sanatize(number)] = name
end
contacts
end
def contact_numbers
contacts_from_file.keys
end
def contact_name
contacts_from_file[number]
end
And here's the JSON file:
{
'1**********' => 'Big Bird'
'1**********'} => 'Josh'
}
If anybody could help me and tell me why the data_from_file is "undefined" it would be extremely helpful, thank you ahead of time.
You never define data_from_file, you just try to read from it in the contects_from_file method.
Perhaps you meant numbers_from_file instead of data_from_file?

How can I export existing AWS ELB policies? undefined method 'reduce'

We want to export our ELB configurations for re-use. I can get the ELB configs with:
all_elbs = Fog::AWS::ELB.load_balancers.all()
But this returns a failure:
all_policies = Fog::AWS::ELB.policies.all()
#=> /Library/Ruby/Gems/2.0.0/gems/fog-aws-0.0.6/lib/fog/aws/models/elb/policies.rb:20:
#=> in `munged_data': undefined method `reduce' for nil:NilClass (NoMethodError)
Ultimately, I want to be able to recreate a ELB based on an existing ELB.
That error message means that on line 20 of policies.rb there is code like foo.reduce and foo happens to be nil.
If we look at the source code of the gem, we see:
def munged_data
data.reduce([]){ |m,e| # line 20
So, the problem is that data is nil when the munged_data method is called. We see on line 8 of the same file that data is defined via a simple attr_accessor call. I cannot tell for sure where that should have been set. (There are 227 instances of #data = or data = in the gem.) This seems like a bug in the AWS gem, unless you were supposed to call some method before calling .all on policies.
Tracing further, we see that policies is defined in load_balancer.rb on line 154 as:
def policies
Fog::AWS::ELB::Policies.new({
:data => policy_descriptions,
:service => service,
:load_balancer => self
})
end
Assuming that the data passed to the method is used directly as the #data instance variable, then the problem is that policy_descriptions returned nil.
The implementation of policy_descriptions is:
def policy_descriptions
requires :id
#policy_descriptions ||= service.describe_load_balancer_policies(id).body["DescribeLoadBalancerPoliciesResult"]["PolicyDescriptions"]
end
If service.describe_load_balancer_policies(id).body["DescribeLoadBalancerPoliciesResult"] returned nil (or any object that did not have a [] method) this method would have thrown an error. So, my deduction is that this returned something like a hash, but that hash has no "PolicyDescriptions" key.
From there...I don't know.

riak content_type no method error

I have the 4 node riak setup running on my os x machine. I have the following program -
require 'riak'
class RiakClient < Riak::Client
#attr_accessor :bucket
def initialize(hosts="")
return Riak::Client.new(:nodes => [{:http_port => 8091},{:http_port =>8092},{:http_port=>8093},{:http_port =>8094}])
end
def get_me(bucket, key)
obj = self.bucket(bucket).get(key)
puts obj.data
end
def put_me(bucket, key, data, content_type)
obj=self.bucket(bucket).get_or_new(key)
puts obj.class
obj.content_type=content_type
obj.raw_data=data
obj.store
end
end
if __FILE__ == $0
my_client=RiakClient.new
my_client.put_me("doc", "index.html", "some data goes here", "text/html")
hash=my_client.get_me("doc", "index.html")
end
I am getting the following error
NilClass
riak_client.rb:32:in `put_me': undefined method `content_type=' for nil:NilClass (NoMethodError)
from riak_client.rb:42:in `<main>'
Do I have to import the RiakBucket and RiakObject classes? It seems that the RiakBucket methods cannot be accessed here?
The actual question here is: why does get_or_new return nil?
It's probably because your initialize() method returns a new Riak::Client, but the Riak::Client that is your parent object never gets initialized. Try putting a call to super instead of the return Riak::Client.new in initialize.
Subclassing Riak::Client is a bit dubious here. I would tend to delegate to it instead.

Adding object to array of arrays

I am trying to add an object to an array of arrays, but when i do, i am recieving an error in my array of array unit tests, stating :- "undefined method 'has_key' for nil:NilClass". However, if i try and add a string or number to the array of array, it works absolutely fine.
I set up my array of arrays like this
#array_of_array= Array.new(5) { Array.new(3) }
Now if I try to do this
#array_of_array[0][0] = MyObject.new
Then if I run my unit tests against #array_of_array, i get the error.
But if I try to do this
#array_of_array[0][0] = 'Test'
Theres no problem.
--Edited---
Heres failing test
it "should place object in correct starting position" do
array_of_array= Array.new(5) { Array.new(3) }
array_of_array[1][0] = MyObject.new
array_of_array.should eql('fail on purpose..want to see output')
end
Im new to ruby, so unsure of where im going wrong. Thanks
Like Claw said, the error probably means that your MyObject.new statement is returning a nil object for some reason. Then you're trying to call the function 'has_key' of that nil object.
Does your MyObject class throw an exception if you use .new! instead of .new ? If so, you could see why it's failing to return a proper MyObject object.
Edit
To catch an exception inside your 'new' method for the MyObject model, you could do something like:
def new
begin
#whatever is done in this method
rescue => exception
puts exception.message
end
end

Resources