Ruby classes with namespaces - ruby

Why is this not legal name-spacing ? We use this often with our ActiveRecord classes. Does AR do something magical?
$ irb
1.9.3-p194 :001 > class F::B
1.9.3-p194 :002?> end
NameError: uninitialized constant F
from (irb):1
from /Users/bob/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

Because F is not defined before you reference it.
You must first define F as a Class or Module. Try this:
module F; end # OR class F; end
class F::B; end
f = F::B.new # => #<F::B:0x007fba3c1046d8>

I think you're forgetting about modules.
1.9.3p429 :001 > module F
1.9.3p429 :002?> class B
1.9.3p429 :003?> end
1.9.3p429 :004?> end
=> nil
1.9.3p429 :005 > F::B.new
=> #<F::B:0x0000000082a230>
1.9.3p429 :006 >
If the module is defined before the class, it will work:
module F; end
class F::B; end

2.0.0p247 :001 > module F;end
=> nil
2.0.0p247 :002 > class F::B;end
=> nil
2.0.0p247 :003 > F
=> F
2.0.0p247 :004 > F::B
=> F::B

Related

Calling a module function in a ruby module

I want to call a module function to define a constant in a utility module in ruby. However, when I try this I get an error message. Here comes the code and the error:
module M
ABC = fun
module_function
def self.fun
"works"
end
end
Error message:
NameError: undefined local variable or method `fun' for M:Module
Any ideas? I also tried it without self and with M.fun but no success...
It is just that the method is not defined when you assign fun to ABC. Just change the order:
module M
def self.fun
"works"
end
ABC = fun
end
M::ABC
#=> "works"
If you dislike the order (constants below methods), you might want to consider to have the method itself to memorize its return value. A common pattern looks like:
module M
def self.fun
#cached_fun ||= begin
sleep 4 # complex calculation
Time.now # return value
end
end
end
M.fun
# returns after 4 seconds => 2017-03-03 23:48:57 +0100
M.fun
# returns immediately => 2017-03-03 23:48:57 +0100
Test this in you irb console:
$ irb
2.3.3 :001 > module M
2.3.3 :002?> def self.fun
2.3.3 :003?> "worked"
2.3.3 :004?> end
2.3.3 :005?>
2.3.3 :006 > ABC = fun
2.3.3 :007?> end
=> "worked"
2.3.3 :008 > M
=> M
2.3.3 :009 > M::ABC
=> "worked"
2.3.3 :010 >
The fact is that now you defined self.fun before using it.
In your code you used the method before defining it.

IPSocket ruby NameError error?

When using IRB with input, getting error:
IPSocket.getaddress("localhost")
Error:
NameError: uninitialized constant IPSocket
Just add top before using the class :
require 'socket'
See this socket/ipsocket.c.
Example :-
2.1.0 :022 > require 'socket'
=> true
2.1.0 :023 > IPSocket.getaddress("localhost")
=> "::1"
2.1.0 :024 >

NoMethodError: undefined method `zone' for Time:Class

How do i use Time.zone in ruby if I am not using rails
I want to do Time.now but that's available in rails but not ruby
I thought that
require 'time'
would fix this and make it available in ruby but it didn't and I get
NoMethodError: undefined method `zone' for Time:Class
I don't know, what do you mean. But I think it should work as below :
(arup~>~)$ pry --simple-prompt
>> Time.now
=> 2014-04-09 23:19:04 +0530
>> Time.now.strftime('%Z')
=> "IST"
>> Time.now.strftime('%z')
=> "+0530"
>> Time.now.zone
=> "IST"
Documentation : #strftime and #zone .
You've tried to use zone as if it were a class method (Time.zone) [1]. If you want to use a class method:
1.9.3-p448 :007 > Time.now.zone
=> "EDT"
But Time.now is just a nice way of instantiating your own instance of Time[2]. So you're really just doing this (calling an instance method):
1.9.3-p448 :009 > time = Time.new
=> 2014-04-09 15:14:01 -0400
1.9.3-p448 :010 > time.zone
=> "EDT"
[1] http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/
[2] http://ruby-doc.org/core-1.9.3/Time.html#method-c-now

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

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

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.

Resources