How do I fix a NoMethodError? - ruby

I did a fresh install on a MacBook Pro, and installed Mavericks, MacTex, Textmate and Texlive.
I am trying to work with some LaTex documents and I get this error on build:
undefined method `+' for nil:NilClass (NoMethodError).
In previous uses I did not see this error.
Below is the script I think I need to tweak but I do not know how. I found guidance in "Ruby undefined method `+' for nil:NilClass (NoMethodError)", but it does not appear to be applicable.
I am also suspicion of the MacTex download via Chrome, I checked that it was ok in Terminal, ran a checksum, and it was, but the MacTex site advises against using Chrome.
Script with a "problem:"
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
# coding: utf-8
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/process"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/htmloutput"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/save_current_document"
# To enable the typesetting of unsaved documents, you must change the “Save” setting of
# this command to “Current File” and add the variable TM_LATEX_AUTOSAVE to TextMate's
# Shell Variables preferences. Be warned that your document must be encoded as UTF-8 if
# you excercise this option — becauseTextMate.save_current_document cannot know the file
# encoding you prefer.
TextMate.save_current_document unless ENV["TM_LATEX_AUTOSAVE"].nil?
texMate = ENV["TM_BUNDLE_SUPPORT"] + "/bin/texMate.py"
engine_version = TextMate::Process.run(texMate, "version")
TextMate::HTMLOutput.show(:title => "Typesetting “#{ENV["TM_DISPLAYNAME"] || File.basename(ENV["TM_FILEPATH"])}”…", :sub_title => engine_version) do |io|
TextMate::Process.run(texMate, 'latex', '1', :interactive_input => false) do |line|
io << line
end
end
::Process.exit($?.exitstatus || 0) # exitstatus is nil if our process is prematurely terminated (SIGINT)
Any help would be great, thanks.

The error you received happens when you try to use the method + on nil:
nil + 'something'
In your code the '+' sign appears in 4 places:
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/process"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/htmloutput"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/save_current_document"
...
texMate = ENV["TM_BUNDLE_SUPPORT"] + "/bin/texMate.py"
Which means that one of either ENV["TM_SUPPORT_PATH"] or ENV["TM_BUNDLE_SUPPORT"] returns nil.
The ENV construct reflects the content of your machine's environment variables, therfore you should make sure the environment variables TM_SUPPORT_PATH and TM_BUNDLE_SUPPORT are set.

Problem solved. I deleted Textmate and then relied on Hazel to delete all affiliated files. I used TexLive to update all packages, ... just an overhaul. Following Mactex guidance using Safari for all future downloads, including the new download of Textmate, Installed Textmate, then followed this guidance, How and "Why to use TextMate for LaTeX," by Kelle, http://www.astrobetter.com/how-and-why-to-use-textmate-for-latex/#comment-595219 ... by the way excellent blog for help with Teaching. I then did a restart, which may not be necessary. Works wonderfully. I cannot comment on the value of the tweaking above, Red Herrings abound, the extent of the absenteeism may have indicated the initial installation was off (a guess). Thanks

I had a similar problem, all the builts stoped working after I cleaning up some bundles that I do not need and installing some new ones. The solution was that I deinstalled the Bundle "Bundle Support", even if it says "no not uninstall" in the description.
Reactivating "Bundle Support" solved this issue for me.

Related

Strange results for the Gem.latest_version_for(name) method

I am working on a gem related utility and I have observed strange results using Gem.latest_version_for method. Here are some observations under irb:
irb(main):001:0> Gem.latest_version_for('rails').to_s
=> "5.2.2"
irb(main):002:0> Gem.latest_version_for('gosu').to_s
=> "0.7.38"
Note how the first line, gets the correct version of rails, 5.2.2 as I write this and checking with rubygems.org confirms this. The query for the gosu gem returns 0.7.38 which is wildly wrong. The correct answer should be 0.14.4
I am at a loss to explain what is happening here.
I can confirm that my host is https://rubygems.org and
C:\Sites\mysh
8 mysh>ruby --version
ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]
C:\Sites\mysh
9 mysh>gem --version
2.5.2
The latest version available for i386-mingw32 platform is 0.7.38. You'll note this comports with what your ruby version is reported as.
https://rubygems.org/gems/gosu/versions
latest_version_for calls latest_spec_for, which calls Gem::SpecFetcher.spec_for_dependency with only the name of the gem as an argument. spec_for_dependency takes another argument, matching_platform, which defaults to true.
It looks like latest_version_for is scoped to your current platform thru that chain, with the matching_platform default. The gem install command might treat i386/x386 as the same/equivalent and allow them.
spec_for_dependency
if matching_platform is false, gems for all platforms are returned
You should be able to mirror the latest_spec_for method and pass in the multi_platform argument to override. Something like
dependency = Gem::Dependency.new name
fetcher = Gem::SpecFetcher.fetcher
spec_tuples, _ = fetcher.spec_for_dependency dependency, true # true added here
With the excellent help of Jay Dorsey, I think I have made some progress here. What I need to say is too large to fit in a comment and is the actual answer to the question about the odd behavior. Well at least I am pretty sure that it is.
As mentioned above: latest_version_for calls latest_spec_for, which calls Gem::SpecFetcher.spec_for_dependency.
The key is that that method then calls Gem::SpecFetcher.search_for_dependency. This is a long rambling method. I want to focus of one line that occurs after the specs have be obtained:
tuples = tuples.sort_by { |x| x[0] }
This sorts the tuples which are an array of [spec, source] arrays. It sorts them in ascending version/platform (as far as I can tell)
Now we return to the Gem class method latest_spec_for(name) and in particular the line:
spec, = spec_tuples.first
This grabs the first sub-array and keeps the spec and discards the source.
Note that it grabs the first element. The one with the lowest version number. This is normally not a problem because for the vast majority of gems, there will be only one spec present. Not so for the gosu gem. Here there are three due to the fact that gosu contains platform specific code. It seems to grab specs for the two Gem platforms ("ruby" and "x86-mingw32") and also the ruby platform (i386-mingw32).
To test my idea, I created the file glmp.rb (get last monkey patch) Here it is:
# The latest_spec_for(name) monkey patch.
module Gem
# Originally in File rubygems.rb at line 816
def self.latest_spec_for(name)
dependency = Gem::Dependency.new name
fetcher = Gem::SpecFetcher.fetcher
spec_tuples, = fetcher.spec_for_dependency dependency
spec_tuples[-1][0]
end
end
Now I know monkey patching is frowned upon, but for now this is just to test the idea. Here are my results:
36 mysh>=Gem.latest_version_for('gosu')
Gem::Version.new("0.7.38")
C:\Sites\ideas\gem_usage
37 mysh>ls
gem_latest.rb gem_usage.rb glmp.rb
C:\Sites\ideas\gem_usage
39 mysh>=require './glmp'
true
C:\Sites\ideas\gem_usage
40 mysh>=Gem.latest_version_for('gosu')
Gem::Version.new("0.14.4")
While I can use this hack to solve my problem for now, I think I will raise an issue with rubygems bringing up this matter.

Ohai thinks my plugin is version 6. Why?

I'm trying to write a plugin for ohai. It seems like a pretty straightforward task:
Ohai.plugin(:Uname) do
provides 'uname'
depends 'kernel'
collect_data do
uname Mash.new
uname[:message] = `uname -a`
end
end
To me this looks like the online examples provided by Opscode, O'Reilly and others. But here's what happens when I try to test it:
% irb -rohai
irb(main):001:0> Ohai::Config[:plugin_path] << "."
=> ["/home/ll0359/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/ohai-8.3.0/lib/ohai/plugins", "."]
irb(main):002:0> o = Ohai::System.new
=> #<Ohai::System:0x007fed82e43078 #plugin_path="", #data={}, #provides_map=#<Ohai::ProvidesMap:0x007fed82e42fd8 #map={}>, #v6_dependency_solver={}, #d82e42f38 #controller=#<Ohai::System:0x007fed82e43078 ...>, #v6_plugin_classes=[], #v7_plugin_classes=[]>, #runner=#<Ohai::Runner:0x007fed82e42ec0 #prp:0x007fed82e42fd8 #map={}>, #safe_run=true>>
irb(main):003:0> o.all_plugins
And here's where the fun begins. I get this output, over and over and over:
[2015-05-20T03:13:09+00:00] WARN: Plugin Definition Error: <./ohai_uname.rb>: collect_data already defined on platform default
[2015-05-20T03:13:09+00:00] WARN: [DEPRECATION] Plugin at ./test_ohai.rb is a version 6 plugin. Version 6 plugins will not be supported in future releases....
your plugin to version 7 plugin syntax. For more information visit here: docs.chef.io/ohai_custom.html
(the text on my second line was clipped by my screen but you get the idea)
I've tried running this code with and without the 'depends' line. Same result.
I've tried running this code with and without the Mash line, substituing 'uname uname -a' for the assignment line. Same result.
I've tried running with and without passing ":linux" as a parameter to collect_data. The only difference is I get a warning about collect_data(:linux) already being defined instead of :default.
I've tried renaming the plugin to a random 8 character identifier just in case it was tripping over being called :Uname. Same result.
I've tried passing "uname" (capital and lower) as a parameter to o.all_plugins. Same result.
So my questions are:
Why does ohai (8.3, running under Ruby 2.2.1) think this is a version 6 plugin? I can't see anything in it that would make it look like it's not version 7.
How can I get this working?
Thanks
Note to self: Next time you do this, don't try to test from the directory your plugin is in and add "." to your plugin_path. Moving to a different directory and adding the absolute path to the plugin solved the problem.
I plan to leave this up in case someone else has this happen to them.

Padrino Tutorial: Can't Modify Frozen String (Runtime Error)

I am following the Padrino tutorial from here:
https://www.padrinorb.com/guides/blog-tutorial
I am copy and pasting the commands but I quickly ran into an error I don't understand:
$ padrino g controller posts get:index get:show
create app/controllers/posts.rb
create app/views/posts
apply tests/shoulda
/Users/waprin/.rvm/gems/ruby-2.1.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators/controller.rb:66:in `prepend': can't modify frozen String (RuntimeError)
from /Users/waprin/.rvm/gems/ruby-2.1.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators/controller.rb:66:in `create_controller'
This might be a bit late, but in case anyone else runs across this error (and because I just worked through the same tutorial) I'll post anyway...
It looks like there's an issue when generating controllers if a test component is specified. In this case you're using shoulda, but the same happens when using rspec and maybe others. It's been reported as a bug: https://github.com/padrino/padrino-framework/issues/1850 and has been fixed, but isn't yet part of a stable release.
One option to fix this would be to change your Gemfile to work with the latest from their github repo. To do this delete your GemFile.lock file, and comment out the line under 'Padrino Stable Gem' in your GemFile:
gem 'padrino', '0.12.4'
then uncomment the line under 'Or Padrino Edge':
gem 'padrino', :github => 'padrino/padrino-framework'
then re-run bundle install.
Of course, you'll no longer be running the stable release, and that may come with other trade-offs.
As a side-note, I believe that the guide on that page is fairly out of date. I also needed to replace:
get :index do
#posts = Post.all(:order => 'created_at desc')
render 'posts/index'
end
with:
get :index, :provides => [:html, :rss, :atom] do
#posts = Post.order('created_at desc')
render 'posts/index'
end
in the Post controller as the active record interface has changed since the time that the guide was written.
I was able to sole this problem by simply going to padrino gem path.
For me it was:
/Users/ahmadhassan/.rvm/gems/ruby-2.2.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators
open controller.rb and change line number 61:
path = #controller
to
path = #controller.dup

Call one Ruby Script from Another

I am having a perplexing problem. I want to call one ruby script from another.
With this in mind, I create a testscript.rb and executed it, it contains this code,
require './paypal.rb'
puts paypal['L_AMT0']
This code returns a number, which is my paypal balance. It relies on a paypal.rb file which uses the ruby-paypal gem. When I do ruby testscript.rb I get the output of my paypal balance, which means it is working properly. This tells me that my method for calling one RB from another is okay, since, in the above scenario, testscript.rb is getting a variable that is returned from paypal.rb.
Using this same logic, I inserted the above code into another program which is called SiriProxy. It is a ruby program. I need it to get my paypal balance.
So Inside that program, I did a require paypal.rb, it failed because it could not find it, so I set an absolute path in require which fixed it.
However, when SiriProxy (the other ruby rb giving me an issue) trys to run puts paypal['L_AMT0'] it results in an error and ends the program.
This is the error,
[Info - Plugin Manager] Say: Checking Paypal Balance
/home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/gems/siriproxy-0.3.0/plugins/siriproxy-example/lib/siriproxy-example.rb:47:in `block in <class:Example>': undefined local variable or method `paypal' for #<SiriProxy::Plugin::Example:0x931a228> (NameError)
from /home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/bundler/gems/cora-1edcfb9073d5/lib/cora/plugin.rb:47:in `instance_exec'
from /home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/bundler/gems/cora-1edcfb9073d5/lib/cora/plugin.rb:47:in `block (2 levels) in process'
In the above output it appears the issue is it does not understand "paypal", as seen here:
undefined local variable or method `paypal'
However, I do not understand why, since in testscript.rb I do the exact same thing and it works.
Can anyone help? Thank you.
Seems like #CodeGnome is right.
From the Kernel documentation:
require(name) → true or false
Loads the given name, returning true if successful and false if the
feature is already loaded.
require_relative(string) → true or false
Ruby tries to load the library named string relative to the requiring
file’s path. If the file’s path cannot be determined a LoadError is
raised. If a file is loaded true is returned and false otherwise.
Loading Files from the Current Directory
I don't know anything about your library or its internals, but it looks like your require statement may be wrong. If you want to load a file from the current directory in Ruby 1.9.3, you should use:
require_relative 'paypal'
Bundler and Gems
If it's a gem that you've installed as part of a bundle (e.g. the gem is defined in a Gemfile), then providing a path in your require statement is wrong. Instead, you need to require the bundled gem as follows:
require 'bundler/setup'
require 'paypal'

Ruby separate large source files into multiple files

I am writing a Ruby script which was supposed to be a small thing but has grown quite large, way to large to have everything crammed into one source file. So I am trying to separate the project into different files. I have four classes and I want to put each in its own separate source file.
What I did:
I moved all of the classes into their own files so now I have this
proj/GoogleChart.rb
proj/BarChart.rb
proj/PieChart.rb
proj/GroupedBarChart.rb
Now that they are in other files I am getting uninitialized constant GoogleChart (NameError) in all of my subclasses on the line where I inherit from GoogleChart, i.e.
require 'GoogleChart'
BarChart < GoogleChart
Can anyone tell me what is wrong?
Thanks
EDIT
Using ruby version 1.8.4
Also I have tried using the absolute path:
require 'C:/Documents and Settings/proj/GoogleChart.rb' and this is still producing a NameError
In Ruby 1.8.x, the . is part of your load path. So you should at least try to debug that by including something like:
puts $:
require 'GoogleChart'
class BarChart < GoogleChart
end
and load that in an IRB session:
Open the session in your directory proj.
Enter there require 'BarChart'
Look at the result.
For me it is:
c:\apps\ruby\test\proj>irb
irb(main):001:0> require 'BarChart'
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/site_ruby/1.8
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/site_ruby/1.8/i386-msvcrt
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/site_ruby
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/vendor_ruby/1.8
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/vendor_ruby/1.8/i386-msvcrt
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/vendor_ruby
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/1.8
C:/Users/mliebelt/.pik/rubies/Ruby-187-p334/lib/ruby/1.8/i386-mingw32
.
=> true
So the require is successful for me, and the . is part of the path (as it should). As you can see, I am working with Ruby 1.8.7, I don't know if anything has changed since 1.8.4 that is relevant here.
So please describe exactly how you run your file:
Have you opened a shell to run the file?
What is the current working directory of that shell?
Do you run by double-clicking it?
It only works when you are in your proj directory and run there (with ruby in your shell path) ruby BarChart.rb.

Resources