How do I use an ActionView::Helper in a Ruby script, outside of Rails? - ruby

I am looking to use ActionView::Helpers::NumberHelper from a Ruby script.
What all do I need to require etc.?

~> irb
ruby-1.9.2-p180 :001 > require 'action_view'
=> true
ruby-1.9.2-p180 :002 > ActionView::Base.new.number_to_currency 43
=> "$43.00"

As of Rails 3.2.13, you can do the following:
class MyClass
include ActionView::Helpers::NumberHelper
def my_method
...
number_with_precision(number, precision: 2)
...
end
end
You might need to require 'action_view' too.
Edit: This answer is still valid in Rails 4.2.3.

Related

NameError: uninitialized constant Game

I have a file Word.rb
class Word
attr_accessor :word, :letters
def initialize (word)
##word = word
#letters = word.split('').map{|letter| {:letter => letter, :hidden => true} }
end
end
and another file Game.rb, which will use Word.rb
require_relative ('./Word.rb')
require 'pry'
class Game
attr_accessor :guesses, :guessed_letters, :words, :current_word
def initialize (words)
#guesses = 0
#guessed_letters = []
#words = words
#current_word = current_word
end
end
And I'm getting the following error:
NameError: uninitialized constant Game
When I try to create a instance of Game like this:
game = Game.new(['hello', 'sunshine', 'chipmunk', 'twitch'])
I just am not sure what I am doing wrong since I am requiring the Word.rb file that Game.rb will need. All files are on the same level, nothing is in a subdirectory. Interestingly, I do not get this error once I comment the require_relative line out (but of course, I need that file required). I have also tried not using require_relative and simply using require as well as a couple other varieties: parens/no parens, file extension/no file extension, etc. How do I properly require this file? I also have a lovely and robust array of words sitting in another file that I would like to require to be used and passed into Game.new().
Look What I did
$ mkdir test
$ cd test
$ gedit Word.rb
# and copied your content and saved
$ gedit Game.rb
# and copied you content and saved
$ irb
After IRB session run I did following
2.1.1 :001 > game = Game.new(['asd'])
NameError: uninitialized constant Game
from (irb):1
from /home/shiva/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>'
2.1.1 :002 > require 'game'
LoadError: cannot load such file -- game
2.1.1 :004 > require 'Game.rb'
LoadError: cannot load such file -- Game.rb
2.1.1 :005 > require './Game.rb'
=> true
2.1.1 :006 > game = Game.new(['shiva', 'bhusal'])
=> #<Game:0x00000003085428 #guesses=0, #guessed_letters=[], #words=["shiva", "bhusal"], #current_word=nil>
2.1.1 :007 >
Try like this

How do I test Digest::SHA2.hexdigest in online irb?

I want to see the hash created by the function Digest::SHA2.hexdigest. I do not have Ruby installed, so I went for the online irb. Typing
Digest::SH­A2.hexdige­st("hello"­)
gives
=> #<NameError: uninitialized constant Digest>
Is it possible to add the needed library in any online irb?
You need to do as below :
2.0.0-p0 :003 > require 'digest'
=> true
2.0.0-p0 :004 > Digest::SHA2.hexdigest("hello")
=> "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
2.0.0-p0 :005 >
So do first require 'digest'.
Try in tutorialspoint

Verify version of a gem with bundler from inside Ruby

Is there a way to verify that I have the latest version of a gem from inside a Ruby program? That is, is there a way to do bundle outdated #{gemname} programmatically?
I tried looking at bundler's source code but I couldn't find a straight-forward way. Currently I'm doing this, which is fragile, slow and so inelegant:
IO.popen(%w{/usr/bin/env bundle outdated gemname}) do |proc|
output = proc.readlines.join("\n")
return output.include?("Your bundle is up to date!")
end
A way to avoid external execution:
For bundler 1.2.x
require 'bundler/cli'
# intercepting $stdout into a StringIO
old_stdout, $stdout = $stdout, StringIO.new
# running the same code run in the 'bundler outdated' utility
Bundler::CLI.new.outdated('rails')
# storing the output
output = $stdout.string
# restoring $stdout
$stdout = old_stdout
For bundler 1.3.x
require 'bundler/cli'
require 'bundler/friendly_errors'
# let's cheat the CLI class with fake exit method
module Bundler
class CLI
desc 'exit', 'fake exit' # this is required by Thor
def exit(*); end # simply do nothing
end
end
# intercepting $stdout into a StringIO
old_stdout, $stdout = $stdout, StringIO.new
# running the same code run in the 'bundler outdated' utility
Bundler.with_friendly_errors { Bundler::CLI.start(['outdated', 'rails']) }
# storing the output
output = $stdout.string
# restoring $stdout
$stdout = old_stdout
There is no programmatic way to use outdated command in bundler, because the code is in a Thor CLI file which prints output to the user. Bundler's tests are also issuing the command to the system and checking the output (Link to outdated tests).
It should be fairly simple to write your own method to mirror what the outdated method in cli.rb is doing, though. See the highlighted code here : Link to outdated method in Bundler source. Remove lines with Bundler.ui and return true/false based on the value of out_count
Update: I've extracted 'bundle outdated' into a reusable method without the console output and the exits. You can find the gist here : link to gist. I have tested this on bundler 1.3 and it seems to work.
bundle check list the gems that are out to date, you might want to use it.
Hmmm, sounds like you might want bundle show or gem env
Disappointing, this looks surprisingly difficult.
There are a couple of open issues in bundler where the official line appears to be:
At this point in time, there isn't a documented ruby API.
It's something that's on our list, though.
Looking through the bundler source code cli.rb, it's fairly clear that it's going to be tricky to call from ruby, or reproduce the code in a sensible manner.
Calling methods from CLI will be difficult because they're sprinkled with calls to exit.
Reproducing the code doesn't look fun either because there is quite a lot of bundler logic in there.
Good luck!
checking the source code of latest bundler source code
I could come up with this
https://github.com/carlhuda/bundler/blob/master/lib/bundler/cli.rb#L398
$ irb
1.9.3p327 :001 > require 'bundler'
=> true
1.9.3p327 :002 > def outdated_gems(gem_name,options={})
1.9.3p327 :003?> options[:source] ||= 'https://rubygems.org'
1.9.3p327 :004?> sources = Array(options[:source])
1.9.3p327 :005?> current_spec= Bundler.load.specs[gem_name].first
1.9.3p327 :006?> raise "not found in Gemfile" if current_spec.nil?
1.9.3p327 :007?> definition = Bundler.definition(:gems => [gem_name], :sources => sources)
1.9.3p327 :008?> options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!
1.9.3p327 :009?> active_spec = definition.index[gem_name].sort_by { |b| b.version }
1.9.3p327 :010?> if !current_spec.version.prerelease? && !options[:pre] && active_spec.size > 1
1.9.3p327 :011?> active_spec = active_spec.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? }
1.9.3p327 :012?> end
1.9.3p327 :013?> active_spec = active_spec.last
1.9.3p327 :014?> raise "Error" if active_spec.nil?
1.9.3p327 :015?> outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
1.9.3p327 :016?> {:outdated=>outdated,:current_spec_version=>current_spec.version.to_s,:latest_version=>active_spec.version.to_s}
1.9.3p327 :017?> end
=> nil
1.9.3p327 :018 >
1.9.3p327 :019 >
1.9.3p327 :020 >
1.9.3p327 :021 >
1.9.3p327 :022 > outdated_gems('rake')
=> {:outdated=>true, :current_spec_version=>"10.0.3", :latest_version=>"10.0.4"}
This may not work with earlier version of bundler.

How to use RSpec expectations in irb

I'd want to use [1,2,3].should include(1) in irb. I tried:
~$ irb
1.9.3p362 :001 > require 'rspec/expectations'
=> true
1.9.3p362 :002 > include RSpec::Matchers
=> Object
1.9.3p362 :003 > [1,2,3].should include(1)
TypeError: wrong argument type Fixnum (expected Module)
from (irb):3:in `include'
from (irb):3
from /home/andrey/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
But it doesn't work though it's a valid case. How can I use [1,2,3].should include(1)?
You are close, but calling include on top-level you will be calling Module#include. To get around it you need to remove the original include method so that RSpec's include gets called instead.
First let's figure out where the system include comes from:
> method :include
=> #<Method: main.include>
Ok. It looks like it's defined in main. This is the Ruby top-level object. So let's rename and remove the original include:
> class << self; alias_method :inc, :include; remove_method :include; end
Now we can get down to business:
> require 'rspec'
> inc RSpec::Matchers
> [1,2,3].should include(1)
=> true

Extending uniq method

This is Ruby 1.8 Question:
We all know how to use Array#uniq :
[1,2,3,1].uniq #=> [1,2,3]
However I'm wondering if we can monkey patch it in a way to work with complex objects. The current behavior is like this:
[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq
#=> [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}]
The requested one is:
[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq
#=> [{"three"=>"3"}, {"three"=>"4"}]
To make Array#uniq work for any object you must override two methods: hash and eql?
All objects have a hash method which calculates the hash value for that object, so for two objects to be equal their values when hashed must also be equal.
Example--a user is unique when their email address is unique:
class User
attr_accessor :name,:email
def hash
#email.hash
end
def eql?(o)
#email == o.email
end
end
>> [User.new('Erin Smith','roo#example.com'),User.new('E. Smith','roo#example.com')].uniq
=> [#<User:0x1015a97e8 #name="Erin Smith", #email="maynurd#example.com"]
It already works for me in 1.8.7.
1:~$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
1:~$ irb -v
irb 0.9.5(05/04/13)
1:~$ irb
>> [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq
=> [{"three"=>"3"}, {"three"=>"4"}]
The problem is that Hash#hash and Hash#eql? both give bogus results in Ruby 1.8.6. This is one of the very rare monkey patches I've been willing to perform, because this bug seriously breaks a lot of code — in particular memoizing functions. Just be careful with monkey patches that you don't override non-broken behavior.
So:
class Hash
if {}.hash != {}.hash
def hash
# code goes here
end
end
if !{}.eql?({})
def eql?(other)
# code goes here
end
end
end
But if you're doing something where you control the deploy environment, just raise an error if the app gets started with 1.8.6.
How about this?
h={}
[{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].select {|e| need=!h.key?(e) ; h[e]=1 ; need}
#=> [{"three"=>"3"}, {"three"=>"4"}]
I've run into this myself many times. Hash equality in Ruby 1.8.6 is broken:
require 'test/unit'
class TestHashEquality < Test::Unit::TestCase
def test_that_an_empty_Hash_is_equal_to_another_empty_Hash
assert({}.eql?({}), 'Empty Hashes should be eql.')
end
end
Passes in Ruby 1.9 and Ruby 1.8.7, fails in Ruby 1.8.6.
1.8.7 :039 > [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq {|x|x.values}
=> [{"three"=>"3"}, {"three"=>"4"}]
1.8.7 :040 > [{"three"=>"3"}, {"three"=>"4"}, {"three"=>"3"}].uniq {|x|x.keys}
=> [{"three"=>"3"}]
How about something like that? just uniq_by the hash value or hash key via the block.

Resources