undefined method 'execute' for nil:NilClass - ruby

I am making a tool in ruby which can interact with databases.
I am using amalgalite as an adapter for sqlite3.
Code:
require 'amalgalite'
# this is class RQuery
class RQuery
def db_open(db_name)
#db = Amalgalite::Database.new "#{db_name}.db"
make_class
end
def exec_this(query)
#db.execute(query)
end
def make_class
tables_list = exec_this("select name from sqlite_master where type='table'")
tables_list.each do |table|
#class_created = Object.const_set(table[0].capitalize, Class.new)
#class_created.class_eval do
define_singleton_method :first do
RQuery.new.exec_this("select * from #{table[0]} order by #{table[0]}.id ASC limit 1")
end
end
end
end
def eval_this(input)
instance_eval(input)
end
def code
print '>>'
input = gets
exit if input =~ /^q$/
puts eval_this(input)
code
end
end
Now when I am running the code everything works fine until I call table_name.first
It gives output
vbhv#fsociety ~/git/R-Query/bin $ ruby main.rb
Enter the code or q for quit
>>db_open('vbhv')
users
persons
people
programmers
>>Users.first
/home/vbhv/git/R-Query/lib/r-query.rb:36:in `instance_eval': undefined method `execute' for nil:NilClass (NoMethodError)
Did you mean? exec
from /home/vbhv/git/R-Query/lib/r-query.rb:29:in `block (3 levels) in make_class'
from (eval):1:in `eval_this'
from /home/vbhv/git/R-Query/lib/r-query.rb:36:in `instance_eval'
from /home/vbhv/git/R-Query/lib/r-query.rb:36:in `eval_this'
from /home/vbhv/git/R-Query/lib/r-query.rb:43:in `code'
from /home/vbhv/git/R-Query/lib/r-query.rb:44:in `code'
from /home/vbhv/git/R-Query/lib/r-query.rb:44:in `code'
from main.rb:4:in `<main>'
Now the 'execute' function it is talking about is inside amalgalite. What am I doing wrong here?? Thanks in Advance!

The problem in this was that the new class formed dynamically doesn't know about the connection variable '#db'. Hence the code solves the problem.
#class_created.instance_variable_set(:#database, #db)
A big thanks to Jagdeep Singh.

Related

Celluloid 0.17.3 giving unexpected "undefined method" error

I have started using Celluloid gem this morning for that first time. I am following this Railscasts tutorial and trying to figure things out.
I have a class called "SomeClass" and it has only one method. Here is the code:
require 'celluloid'
class SomeClass
include Celluloid
def initialize(name)
#name = name
end
def assholify()
puts "#{#name} has become an ASSHOLE."
end
end
When I create new instances of the class and call its method (with a bang i.e. "assholify!"), I am getting the undefined method 'assholify!', error. But Celluloid is supposed to trigger the method asynchronously when it is called with a bang. So here is how I am calling the method:
names = ['John', 'Tom', 'Harry']
names.each do |name|
n = SomeClass.new name
n.assholify!
end
Here is the full backtrace of the error:
I, [2016-09-09T11:28:02.488618 #3682] INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
/home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:42:in `rescue in check': undefined method `assholify!' for #<SomeClass:0x10897dc> (NoMethodError)
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:39:in `check'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:26:in `dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:16:in `dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/cell.rb:50:in `block in dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/cell.rb:76:in `block in task'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/actor.rb:339:in `block in task'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/task.rb:44:in `block in initialize'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/task/fibered.rb:14:in `block in create'
from (celluloid):0:in `remote procedure call'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:45:in `value'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/proxy/sync.rb:22:in `method_missing'
from some_class.rb:18:in `block in <main>'
from some_class.rb:16:in `each'
from some_class.rb:16:in `<main>'
Why am I getting this error? Is it the right way to call the function? Also how do I get rid of Celluloid 0.17.3 is running in BACKPORTED mode. warning?
The undefined method error occurred because actor methods are not called with a bang in the recent versions of celluloid gem. Instead you call the method like this: n.async.assholify. So here is what the code should look like:
names = ['John', 'Tom', 'Harry']
names.each do |name|
n = SomeClass.new name
n.async.assholify # Instead of "n.assholify!"
end
For "Celluloid 0.17.0 is running in BACKPORTED mode" warning, take a look at this wiki. Backported Mode is the default, for a limited time. If you use require 'celluloid/current' instead of require 'celluloid', you should not see this warning.

Rails 4: Undefined method on module

I have a module in app/misc/dsl/builder.rb that has this code
module Dsl
class Builder
def initialize(context, &block)
return if not block_given?
parent_context = block.binding.eval "self"
parent_context.extend Proxy
parent_context.object = context
parent_context.instance_eval &block
end
end
def self.set_context(context, &block)
Dsl::Builder.new(context, &block)
end
end
Note: this directory misc is preloaded in application.rb
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**/}'),
Rails.root.join('app', 'misc', '{**/}')
]
Then, somewhere in the text (lets say at foo.rb) I have this code:
Dsl.set_context(obj) do
#some code with obj receiving messages
end
The test stack we are using consists on Zeus+Guard+Rspec. Now, lets say I rewrite the code to something not working
Dsl.set_context(obj) do
asdqwe #this message does not exists
end
From times to times, I receive this baffling message
1) SomeOtherClass search_hash receiving keywords params should query for those keywords
Failure/Error: subject.search_hash
NoMethodError:
undefined method `set_context' for Dsl:Module
# ./app/misc/product_query.rb:116:in `base_search_hash'
# ./app/misc/product_query.rb:25:in `search_hash'
# ./spec/misc/product_query_spec.rb:78:in `block (4 levels) in <top (required)>'
# -e:1:in `<main>'
instead of the correct message that should be regarding undefined method asdqwe
Any clue about this?
Look here
it says:
Rails 3 has been updated such that classes/modules (henceforth, C/M)
are lazy loaded from the autoload paths as they are needed
so, you can do require_relative 'app/misc/dsl/builder.rb' in your rspec_helper.rb (can it be better with just require?) The problem must be that the loader doesn't know in advance where to find Dsl.set_context, but he will know once you have referenced Dsl::Builder
Hope it helps

Unexpected Method Call

I'm using mongomapper to store pages in a db, and I index them first. In the index method, I loop through each word, and check to see if it is already in the words hashmap. If not, I add an empty array to the hash, then push its location to the array.
def index_words
#words = self.body.split(" ")
#words.each_with_index do |word,i|
if self.words[word.stem].nil?
self.words[word.stem] = []
end
puts "Called from #{caller[0]}"
self.words[word.stem].push(i)
end
end
When I run this, I get an undefined method error, saying that self.words[word.stem] is nil. Furthermore, this method is actually being called from the loop, when it's only called once in the constructor:
def initialize(*args)
super
index_words
end
The error message is:
p = Page.new({author: 'Michael',url: 'michaelfine.me',title: 'Michael Fine',body: 'Body Text'})
called fromPage.rb:19:in `each'
NoMethodError: undefined method `push' for nil:NilClass
from Page.rb:24:in `block in index_words'
from Page.rb:19:in `each'
from Page.rb:19:in `each_with_index'
from Page.rb:19:in `index_words'
from Page.rb:14:in `initialize'
from (irb):103:in `new'
from (irb):103
from /Users/Michael/.rvm/rubies/ruby-1.9.3-p286/bin/irb:16:in `<main>'

Why do I get "Undefined method ::new" in simple classes?

I am writing an ATM-system-like socket/server solution. I would appreciate if someone could tell me what I'm missing. For some reason, I get the following error running my stub test suite:
# Running tests:
.E
Finished tests in 0.002411s, 829.4384 tests/s, 414.7192 assertions/s.
1) Error:
test_0001_connects_to_a_host_with_a_socket(AtmClient::connection):
NoMethodError: undefined method `new' for #<SpoofServer:0x9dce2dc #clients=[], #server=#<TCPServer:fd 5>>
/media/wildfyre/Files/Programming/KTH/progp/Atm/spec/client/SpoofServer.rb:12:in `start'
/media/wildfyre/Files/Programming/KTH/progp/Atm/spec/client/client_spec.rb:12:in `block (3 levels) in <top (required)>'
2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
My minispec file is:
require_relative '../spec_helper.rb'
require_relative '../../lib/AtmClient.rb'
require_relative 'SpoofServer.rb'
describe AtmClient do
it "can be created with no arguments" do
AtmClient.new.must_be_instance_of AtmClient
end
describe 'connection' do
it "connects to a host with a socket" do
spoof = SpoofServer.new.start
client = AtmClient.new.connect
spoof.any_incoming_connection?.must_be true
spoof.kill
end
end
end
My SpoofServer file is:
require 'socket'
class SpoofServer
def initialize
end
def start
#clients = []
#server = TCPServer.new 1234
#listener_thread = new Thread do
#clients.add #server.accept
end
end
def any_incoming_connection?
#clients.size > 0
end
def kill
#listener_thread.exit
#clients.each {|c| c.close}
end
end
As you can read in the trace of the calls stack:
NoMethodError: undefined method `new' for #<SpoofServer:...>
/.../spec/client/SpoofServer.rb:12:in `start'
The error is inside the start method defined in SpoofServer.rb, at line 12, the wrong line is:
#listener_thread = new Thread do
That should be:
#listener_thread = Thread.new do
As you have written it, what you are actually doing is to calling the new method passing the Thread class as argument. Since no new method is defined for instances of the SpoofServer class you get the NoMethodError exception.
In body of instance method SpoofServer#start, you can't call the class method SpoofServer.new by new.

Confusion with IRB output in Ruby when object#initialize is overloaded

What I actually trying to see when no 'initialize' method is given to an class definition then the class as you said should call the "Object#initialize",which here I tried to customize and see if it has been called or not. With that approach I reached to a conclusion(although that's wrong), when I typed "ob = A .new" that yes I can overload the Object#initialize method.But all has been ended up with the below exception. Then I thought I did something wrong in my customization.So I tried to create the object creation within an exception block and when I typed "begin" and pressed "ENTER" - i got the same error.
>> class A
>> def Object.new initialize
>> p "hi"
>> rescue
>> end
>> end
=> nil
>> begin # <~~~ Here I have pressed on ENTER
"hi" #<~~~~ How was it print out?
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:94:in `Token': undefined method `set_backtrace' for "hi":String (NoMethodError)
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:348:in `block in lex_init'
from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
from /usr/lib/ruby/1.9.1/irb/slex.rb:221:in `match_io'
from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels) in each_top_level_statement'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement'
from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start'
from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch'
from /usr/lib/ruby/1.9.1/irb.rb:69:in `start'
from /usr/bin/irb:12:in `<main>'
#ubuntu:~$
Now my questions are -
How has the "hi" been printed?
What is the cause of the error as printed above?
If such initialize definition is not allowed,then why has the error not come after I ended with the class definition?
EDIT
As per #casper I tried below:
>> def Object.new
>> p "hi"
>> end
=> nil
>> begin
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:96: stack level too deep (SystemStackError)
But here no "hi" printed back.
So what made the "hi" to print back in the first case?
What exactly are you trying to do? You just redefined Object.new, so there is no surprise you make everything go haywire.
You can basically get the same effect by just:
>> def Object.new
>> end
>> [press enter]
KABOOM
The reason "hi" is printed is that someone just called Object.new, probably the irb REPL loop, and it expected an object, but instead it gets gobledygook.
You can also try this:
def Object.new *args
p args
end
And you will see funny stuff. However you won't be able to quit irb or do anything useful with it after that. Again: you just broke Object.
To make some sense of it you should read this:
In Ruby, what's the relationship between 'new' and 'initialize'? How to return nil while initializing?
And then you can try this:
class Object
class << self
alias :old_new :new
end
end
Now you can do:
def Object.new *args
p args
old_new *args
end
This won't break new because you are still calling the old version of it. However you will now be printing out stuff every time someone calls new.

Resources