uninitialized constant Couch::Couchbase (NameError) - ruby

I have this problem:
uninitialized constant Couch::Couchbase (NameError)
./features/step_definitions/lib/couchbase.rb:6:in `get'
./features/step_definitions/StepsLib.rb:130:in `/^I get couch$/'
features/test.feature:4:in `Then I get couch
The code is:
require 'rubygems'
require 'couchbase'
class Couch
def get
client = Couchbase.connect(:bucket => "user", :hostname => "192.168.1.50")
user = client.get("COMMENT-FO-1103")
return user
client.disconnect
end
end
I've been loocking all over, and no clue, I'm no ruby expert.
Thanks.

Try connecting through IRB and see if you get the same error.
Open up an IRB instance and type:
> require 'Couchbase'
You'll get a statement back saying: => true
Then connect as follows:
> c = Couchbase.new("http://localhost:8091/pools/default/buckets/MyBucket")
This should connect you directly to the bucket you wish to operate on.
Then try:
> c.set("mykey", "Some Value")
And you should get a confirmation that the object has been set in the Bucket.
Then use:
> c.get("mykey")
And you should print the value of the object you just set.
Regarding your code above, I'm not sure why exactly you're trying to wrap this call up in a Class? What is your Use case?

I notice on the github page that methods like get aren't run on client itself, but instead are used in a block argument to run like:
client.run { |conn| conn.get("COMMENT-FO-1103") }
That's really all I can think of there. Hope it helps.
I do notice that return user will prevent the line client.disconnect from ever running, as return kicks you out of the method entirely.

Related

Ruby unknown + on trying to join 2 strings

So, I'm learning Ruby and immediately, have stumbled upon something rater peculiar when trying to concatenate 2 strings to one. Here's the code, with irrevelant parts stripped, lets just say Sinatra runs it:
class CMS
# Set the site path root.
#sitePath = "./site"
get '/' do
renderCache = File.readlines(#sitePath + "index.liquid")
end
end
And on loading the page, I am greeted with
NoMethodError at /
undefined method `+' for nil:NilClass
on the renderCache = File.readlines(#sitePath + "index.liquid") line. Why is it refusing to concatenate the strings?
You can't set instance variables at the class level. You need to set them in an instance method.
Look's like you're using sinatra so you can do this:
See here for how to make a "before filter" like one does in Rails apps. This solution is for the modular style of Sinatra app.
To show an example:
class CMS < Sinatra::Base
before do
#sitePath = "./site"
end
get '/' do
renderCache = File.readlines(#sitePath + "index.liquid")
end
end
CMS.run!
You could also keep your existing code if you use a constant instead of an instance variable:
class CMS
# Set the site path root.
SitePath = "./site"
get '/' do
renderCache = File.readlines(CMS::SitePath + "index.liquid")
end
end
To explain how I read your error and looked for the error:
undefined method '+' for nil:NilClass means you're calling + on something which is nil. Referencing the code shows that the nil variable is #sitePath. Undefined instance variables will evaluate to nil. This is different than standard variables, which will raise an undefined variable error.

Writing a Logstash GEM gives an error: undefined local variable or method

Trying to build a gem to use it for Logstash as a filter. I'm using classes and methods from a .jar file.
The following is my Jruby code so far:
# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
require 'java'
require 'Processing.jar'
java_import 'process.Process'
class LogStash::Filters::Process < LogStash::Filters::Base
config_name "process"
StringPath = "/path/to/file/"
ML = JavaUtilities.get_proxy_class('processing.Processing')
#ML = ML.new(StringPath)
public
def register
end
public
def filter(event)
event["result"] = #ML.Process("any string.")
filter_matched(event)
end
end
However, it gave me the following error:
←[31mException in filterworker, the pipeline stopped processing new events, plea
se check your filter configuration and restart Logstash. {"exception"=>#<NoMetho
dError: undefined method 'Process' for nil:NilClass>, "backtrace"=>[
"/path/to/logstash-2.0.0/vendor/local_gems
/dda91dc0/logstash-filter-Process-0.5.0/lib/logstash/filters/processing.rb:54:in 'filter'", "/path/to/log
stash-2.0.0/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/f
ilters/base.rb:152:in 'multi_filter'", "org/jruby/RubyArray.java:1613:in 'each'"
, "/path/to/logstash-2.0.0/vendor/bundle/j
ruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/filters/base.rb:149:in 'mult
i_filter'", "(eval):233:in 'filter_func'", "/path/to/logstash-2.0.0/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/
lib/logstash/pipeline.rb:219:in 'filterworker'", "path/to/log/logstash-2.0.0/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0
-java/lib/logstash/pipeline.rb:154:in 'start_filters'"], :level=>:error}←[0m
NoMethodError: undefined method 'Process' for nil:NilClass
filter at /path/to/logstash-2.0.0
/vendor/local_gems/dda91dc0/logstash-filter-Process-0.5.0/lib/logstash
/filters/Process.rb:54
multi_filter at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/filters/base
.rb:152
each at org/jruby/RubyArray.java:1613
multi_filter at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/filters/base
.rb:149
filter_func at (eval):233
filterworker at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/pipeline.rb:
219
start_filters at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/pipeline.rb:
154
I tried the following:
.
.
.
public
def filter(event)
StringPath = "/path/to/file/"
ML = JavaUtilities.get_proxy_class('processing.Processing')
#ML = ML.new(StringPath)
event["result"] = #ML.Process("any string.")
filter_matched(event)
end
end
But it gave me the error:
SyntaxError: dynamic constant assignment error.
I tried this in a normal jruby file and everything worked with me. Using Logstash's filter however is what seems to be giving me an issue here.
It seems you are struggling with local and instance variables in Ruby. Please see this blog post for more information.
When you call event["result"] = ML.Process(event["text"]) ruby tries to find a local variable named ML which doesn't exist. Therefore you get undefined local variable or method ML.Process(event["text"]). So, messing around with your variables might solve your problem.
#ML is an instance variable and is available in all methods calling it using #ML or self.ML. Please try this:
public
def filter(event)
event["result"] = #ML.Process(event["text"])
filter_matched(event)
end
Things I stumbled upon:
Where do MLVectorPath and MLStopWordPath come from?
What is StringPath? It is assigned but never used.
Do you have a field text? Otherwise change event["text"] into event["message"].
However, I know neither your Java code nor your logstash configuration so these things may be okay. Please let me know if this helps.

Can't understand why I'm getting a `initialize': uninitialized constant Controller::View (NameError)

I'm trying to understand why I'm getting this error and I suspect it's because I have my Controller class and View class in two separate Ruby files. I was told that using require_relative 'filename' should reference all the code from one file into another, but I seem to be missing something. Okay here goes,
In controller.rb file, I have
require_relative 'view'
require_relative 'deck_model'
require_relative 'flashcard_model'
class Controller
def initialize
#deckofcards = Deck.new
#welcome = View.new.welcome
#player_guess = View.new.get_user_guess
#success_view = View.new.success
#failure_view = View.new.failure
end
def run
#Logic to run the game
# #current_card
# #user_guess
puts "Let's see if this prints"
# pull_card_from_deck
end
end
In my view.rb file, I have,
require_relative 'controller'
class View
attr_accessor :userguess
def initialize (userguess = " ")
#userguess = userguess
end
def welcome
system ("clear")
puts "Welcome! Let's play a game."
puts "I'll give you a definition and you have to give me the term"
puts "Ready..."
end
def get_user_guess
#userguess = gets.chomp.downcase
end
def success
puts "Excellent! You got it."
end
def failure
puts "No, that's not quite right."
end
end
However when I run controller.rb, I get the following error,
/Users/sean/Projects/flash/source/controller.rb:11:in `initialize': uninitialized constant Controller::View (NameError)
from /Users/sean/Projects/flash/source/controller.rb:51:in `new'
from /Users/sean/Projects/flash/source/controller.rb:51:in `<top (required)>'
from /Users/sean/Projects/flash/source/view.rb:1:in `require_relative'
from /Users/sean/Projects/flash/source/view.rb:1:in `<top (required)>'
from controller.rb:1:in `require_relative'
from controller.rb:1:in `<main>'
Can anyone please help me figure this out.
You did not post your full code, but it sounds like this is an error caused by the circular dependencies you specified in your project. You have view.rb depending on controller.rb and controller.rb depending on view.rb. The Ruby interpreter will not execute these files simultaneously; it has to execute one and then execute the other.
It looks like it is executing controller.rb first, but it sees that view.rb is required, so it starts executing that. Then in view.rb it sees that controller.rb is required, so it starts executing controller.rb again. Then at some point in controller.rb, you must be creating a new instance of the Controller class. But we aren't done defining the View class yet, so View is undefined and you get an exception while trying to create that controller.
To fix this, you should consider not creating any Controller or View objects until both of the classes are fully loaded.
+1 to #DavidGrayson comment.
If my assumption is correct, your issue is with require_relative 'controller' in your view.rb file.
If you see, it looks like View is requiring Controller then Controller gets loaded which seems to be sending new somewhere to Controller which then sends new to View but it hasn't been completely required.

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.

ruby variable scoping across classes

RuNubie here. I've got a class Login that logs into gmail using the net/IMAP library. What is happening is that I create a new instance of that class, such as:
a = Login.new("username", "gmail.com", "passw")
Then, I'm working on other classes that will do some "stuff" with the mailbox. The problem is that the #imap variable I've defined in Login seems to have disappeared (due to scoping I assume).
This is how #imap is declared in Login class:
#imap = Net::IMAP.new('imap.gmail.com',993,true,nil,false)
So this:
#today = Date.today
#received_today = imap.search(["SINCE", #today.strftime("%d-%b-%Y")]).count.to_s
...returns an error. These are the two errors I've gotten while playing around with this. The first one is when I use imap, the second one is when I try #imap:
NameError: undefined local variable or method `imap' for #<Object:0x10718d2a8>
NoMethodError: undefined method `search' for nil:NilClass
What are the best practices for dealing with a situation like this? Is the only solution to define my methods that do "stuff" in the same class where I'm creating the new instance of Net::IMAP? Is declaring #imap as a global variable $imap a bad practice? So confused, I bet the answer is very simple and obvious too, but I'm just not seeing it. Thanks!
This:
#received_today = imap.search(["SINCE", #today.strftime("%d-%b-%Y")]).count.to_s
won't work because, well, there is no imap in scope at that point and so you get a NameError. When you try it like this:
#received_today = #imap.search(["SINCE", #today.strftime("%d-%b-%Y")]).count.to_s
You get a NoMethodError because instance variables, such as #imap, are automatically created at first use and initialized as nil. Your real #imap is in another object so you can't refer to it as #imap anywhere else.
I think you want a structure more like this:
class User
def imap
if(!#imap)
#imap = Net::IMAP.new('imap.gmail.com', 993, true, nil, false)
# and presumably an #imap.authenticate too...
end
#imap
end
end
class OtherOne
def some_method(user)
#today = Date.today
#received_today = user.imap.search(["SINCE", #today.strftime("%d-%b-%Y")]).count.to_s
end
end
Keep your Net::IMAP localized inside your User and let other objects use it by providing a simple accessor method.
Oh and that global $imap idea, I'll just pretend I didn't see that as globals are almost always a really bad idea.
a shorter way to define the imap variable in the User class, which is pretty much the same as what mu posted:
class User
def imap
#imap ||= Net::IMAP.new...
end
end

Resources