ruby requiring an arbitrary ruby gem in irb session - ruby

I've been playing around with Rails for some time. But now I am attempting to build a ruby gem. And I am using rubymine which builds a gem template for you. In my case it looks like this:
$ ls
bin Gemfile lib Rakefile test
binarytree.gemspec Gemfile.lock LICENSE.txt README.md
merlino#johnmerlino:~/Documents/github/binarytree$
Inside the lib directory, I have a file called binarytree.rb, which contains the following contents:
require "binarytree/version"
module Binarytree
class BinaryNode
attr_accessor :value, :left, :right
def initialize(value=nil)
#value = value
#left = nil
#right = nil
end
def add(value)
if value <= #value
if #left
#left.add value
else
#left = BinaryNode.new value
end
else
if #right
#right.add value
else
#right = BinaryNode.new value
end
end
end
end
class BinaryTree
attr_accessor :root
def initialize
#root = nil
end
def add(value)
if !#root
#root = BinaryNode.new value
else
#root.add value
end
end
def contains(value)
node = #root
while node
if value == node.value
return true
elsif value < node.value
node = node.left
else
node = node.right
end
end
false
end
end
end
What I want to be able to do is run an irb (interactive ruby shell) session, and then be able to require 'binarytree' and have this code inside scope of irb, so I could start playing with it e.g. BinaryTree.new.
Right now I am not sure how to require this in irb:
require 'binarytree'
LoadError: cannot load such file -- binarytree
from /home/merlino/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in require'
from /home/merlino/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:inrequire'
from (irb):1
from /home/merlino/.rvm/rubies/ruby-2.0.0-p0/bin/irb:13:in `'
I am on Ubuntu and I am using rvm to manage gems.
Any ideas?

You have two options:
Go into catalog of your gem and run require './lib/binarytree.rb'
Run rake install inside catalog of your gem - this will build and install this gem into system gems.

I got it working the following way:
1) You first need to edit the gemspec:
binarytree.gemspec
And edit the description and summary lines as so:
spec.description = "binary tree"
spec.summary = "binary tree summary"
Otherwise you will get the following error:
gem build doctor_toons.gemspec
ERROR: While executing gem ... (Gem::InvalidSpecificationException)
"FIXME" or "TODO" is not a description
2) Then run the gemspec as so:
gem build binarytree.gemspec
This should output something that looks like this:
binarytree-0.0.1.gem
3) Now if you are using rvm, make sure you are using the version you want, and run the following:
gem install ./binarytree-0.0.1.gem
The output should look something like this:
Successfully installed binarytree-0.0.1
Parsing documentation for binarytree-0.0.1
Installing ri documentation for binarytree-0.0.1
Done installing documentation for binarytree after 0 seconds
Done installing documentation for binarytree (0 sec).
1 gem installed
4) Then launch irb and require the new gem:
irb(main):001:0> require 'binarytree'

Related

Ruby Minitest assert_equal fails

I have a gemfile with the following:
# frozen_string_literal: true
source "https://rubygems.org"
gem 'cucumber'
gem 'minitest', '~> 5.10', '>= 5.10.3'
gem 'minitest-focus'
gem 'minitest-reporters', '~> 1.1.9'
gem 'rspec'
...
A Cucumber .env file with this to load and require the gems:
require 'bundler'
Bundler.require
And a Ruby file with the following:
require 'minitest/autorun'
require_relative './../../../../RubyProjects/mksta-common/common'
class VerifyApi < MiniTest::Test
include Common
def initialize(has_authorization)
#has_authorization = has_authorization
end
def test_id_correct
assert_equal(20, 20)
end
end
I am receiving this error when attempting to do that assert:
undefined method `+' for nil:NilClass
In Assertions.rb:
def assert_equal exp, act, msg = nil
msg = message(msg, E) { diff exp, act }
result = assert exp == act, msg
if exp.nil? then
if Minitest::VERSION =~ /^6/ then
refute_nil exp, "Use assert_nil if expecting nil."
else
where = Minitest.filter_backtrace(caller).first
where = where.split(/:in /, 2).first # clean up noise
warn "DEPRECATED: Use assert_nil if expecting nil from #{where}. This will fail in Minitest 6."
end
end
result
end
def assert test, msg = nil
self.assertions += 1
unless test then
msg ||= "Expected #{mu_pp test} to be truthy."
msg = msg.call if Proc === msg
raise Minitest::Assertion, msg
end
true
end
Error occurs at the line: "self.assertions += 1" so i am not sure where "assertions" is not being set..
I am wondering if my require process is incorrect, or if i am missing a requirement. Or perhaps Cucumber / Rspec is getting in the way? Any help would be appreciated.
Well, the problem is when you initialize VerifyApi, you did not initialize MiniTest::Test. So the self.assertions is nil.
To solve this problem, you just need to add one more line in the initialize function
super(name)
Of course, you need add one parameter in the function.

Ruby Error: koala no such file to load LoadError

I have installed Ruby (not Rails) on a machine and am trying to run some code based off the koala framework for Facebook.
When I run
gem list
koala is mentioned but when I run the file, I get this error. Rubygems is already installed, I'm not sure what else to do. Any ideas?
Edit:
require 'koala'
require 'json'
#graph = Koala::Facebook::API.new("CAACEdEose0cBANb7YuygrBflSkBrpdalb4e70T5lJgdLPYEh0Uxy5JLPVdukKSiwZAK8g27DnwscSUWNaC0s53ogq6h562LETjYO4sB5lZAMAy8tC0SM9UzqXkk7GKYpaLrkQlgj1oLTdOJhBfq5KJtFxZBkOkpz8HaVPLYp66OnuGkaGOogVseR1tUNXVxToKl6ZCmwHL0i5RHNvMnd")
url = File.open("urls.txt","r")
url.each_line do |line|
id = /[\d]+/.match(line)
begin
temp = #graph.get_object(id)
list = File.open("working.txt", "a")
list.write(id)
list.write("\n")
puts "Worked for #{id}."
rescue
puts "Didn't work for #{id}."
end
end

How to Serialize Object to json in Ruby

I am learning Ruby and am wondering how to serialize a ruby object to json. I am cool using ActiveSupport or any other gems, what is the best way to to this? The following approach doesn't work and fails with
BinaryTree.rb:4:in `require': no such file to load -- json (LoadError)
My question is, what do I install and what require statements would I need to use?
#!/usr/bin/env ruby
require 'pp'
require 'json'
class BinaryTree
attr_accessor :key, :value, :left, :right
def initialize(key=nil,value=nil, left=nil, right=nil)
#key, #value, #left, #right = key, value, left, right
end
def insert(key,value)
if #key.nil?
#key = key
return #value = value
end
if key == #key
return #value = value
end
if key > #key
if #right.nil?
#right = BinaryTree.new
end
return #right.insert(key, value)
end
if #left.nil?
#left = BinaryTree.new
end
return #left.insert(key, value)
end
end
if __FILE__ == $0
bt = BinaryTree.new
bt.insert(5,2)
bt.insert(4,5)
bt.insert(6,3)
bt.insert(9,7)
bt.insert(8,9)
pp bt
puts JSON.encode(bt)
end
Do you have the json gem installed? If not, you'd need to ensure you install that using gem install json first. Once installed, you should be able to do something like the following:
File.open('output_file', 'w') do |f|
f.write(JSON.encode(bt))
end
Using the File.open API with a block is convenient since it will #close the file instance afterward.
Update
If you're on Ruby 1.8 or earlier, you must set up Rubygems first, using the following:
require 'rubygems'
gem 'json'
require 'json'
puts ['test'].to_json

cattr_accessor outside of rails

I'm trying to use the google_search ruby library (code follows) but it complains that 'cattr_accessor is an undefined method' - any ideas why this might be or how I could fix it?
require 'rubygems'
require 'google_search'
GoogleSearch.web :q => "pink floyd"
cattr_accessor seems to be a Rails extension that acts like attr_accessor, but is accessible on both the class and its instances.
If you want to copy the source of the cattr_accessor method, check out this documentation:
# File vendor/rails/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb, line 46
def cattr_accessor(*syms)
cattr_reader(*syms)
cattr_writer(*syms)
end
# File vendor/rails/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb, line 4
def cattr_reader(*syms)
syms.flatten.each do |sym|
next if sym.is_a?(Hash)
class_eval("unless defined? ##\#{sym}\n##\#{sym} = nil\nend\n\ndef self.\#{sym}\n##\#{sym}\nend\n\ndef \#{sym}\n##\#{sym}\nend\n", __FILE__, __LINE__)
end
end
# File vendor/rails/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb, line 24
def cattr_writer(*syms)
options = syms.extract_options!
syms.flatten.each do |sym|
class_eval("unless defined? ##\#{sym}\n##\#{sym} = nil\nend\n\ndef self.\#{sym}=(obj)\n##\#{sym} = obj\nend\n\n\#{\"\ndef \#{sym}=(obj)\n##\#{sym} = obj\nend\n\" unless options[:instance_writer] == false }\n", __FILE__, __LINE__)
end
end
You can get this functionality by including the Ruby Facets gem. Reference the source here:
https://github.com/rubyworks/facets/blob/master/lib/core/facets/cattr.rb
You generally don't need to require all code from the gem. You can selectively require what you want. There are quite a few useful extensions in the gem though.

Printing the source code of a Ruby block

I have a method that takes a block.
Obviously I don't know what is going to be passed in and for bizarre reasons that I won't go into here I want to print the contents of the block.
Is there a way to do this?
You can do this with Ruby2Ruby which implements a to_ruby method.
require 'rubygems'
require 'parse_tree'
require 'parse_tree_extensions'
require 'ruby2ruby'
def meth &block
puts block.to_ruby
end
meth { some code }
will output:
"proc { some(code) }"
I would also check out this awesome talk by Chris Wanstrath of Github http://goruco2008.confreaks.com/03_wanstrath.html He shows some interesting ruby2ruby and parsetree usage examples.
In Ruby 1.9+ (tested with 2.1.2), you can use https://github.com/banister/method_source
Print out the source via block#source:
#! /usr/bin/ruby
require 'rubygems'
require 'method_source'
def wait &block
puts "Running the following code: #{block.source}"
puts "Result: #{yield}"
puts "Done"
end
def run!
x = 6
wait { x == 5 }
wait { x == 6 }
end
run!
Note that in order for the source to be read you need to use a file and execute the file (testing it out from irb will result in the following error: MethodSource::SourceNotFoundError: Could not load source for : No such file or directory # rb_sysopen - (irb)
Building on Evangenieur's answer, here's Corban's answer if you had Ruby 1.9:
# Works with Ruby 1.9
require 'sourcify'
def meth &block
# Note it's to_source, not to_ruby
puts block.to_source
end
meth { some code }
My company uses this to display the Ruby code used to make carbon calculations... we used ParseTree with Ruby 1.8 and now sourcify with Ruby 1.9.
In Ruby 1.9, you can try this gem which extract the code from source file.
https://github.com/ngty/sourcify
In Ruby 2.5 the following works
puts block.source
In ruby 2.7, using the method_source gem (pry depends on it)
Set.instance_method(:merge).source.display
# =>
def merge(enum)
if enum.instance_of?(self.class)
#hash.update(enum.instance_variable_get(:#hash))
else
do_with_enum(enum) { |o| add(o) }
end
self
end
The repo says it works for procs, but I haven't tested it.

Resources