Ruby scopes: Diference between MyClass.new and ::MyClass.new [duplicate] - ruby

This question already has answers here:
Ruby: what does :: prefix do?
(3 answers)
Closed 7 years ago.
I know that the double colon (::) is basically a namespace resolution operator. But in this particular case, I'm not sure in which scope I'm working. Does it mean that I want MyClass class from the ruby core? Sort of like ~ means home directory in bash..

Imagine the following code:
class A
def a
puts 'TOPMOST'
end
end
module B
class A
def a
puts 'NESTED'
end
end
def self.topmost
::A.new.a
end
def self.nested
A.new.a
end
end
B.topmost will print "TOPMOST", and B.nested will print "NESTED".
So, ::A means not “from ruby core”, but rather “from no module.”

Related

Does Ruby's define_method have special access to instance variables? [duplicate]

This question already has answers here:
Calling Instance Variables without #
(4 answers)
Closed 2 years ago.
I am learning Ruby and have stumbled upon some code similar to the one below, which shows the difference between instance variables and class instance variables. I've tested it in my console and it works like described (outputs "John"). What I don't understand is how define_method accesses the #name instance variable without preceding name with a #? Does it have a special capability that allows it to do so?
class User
attr_reader :name
def self.name
"User"
end
def initialize(name)
#name = name
end
define_method(:output_name) do
puts name
end
end
user1 = User.new("John")
user1.output_name #=> “John”
It's about scope
define_method(:output_name) do
puts name
end
The puts name part of this has instance scope.
Therefore it has access to instance methods such as the one generated by
attr_reader :name

ruby attr_accessor/instance method confused [duplicate]

This question already has answers here:
Why do Ruby setters need "self." qualification within the class?
(3 answers)
Closed 4 years ago.
I am trying to understand the attr_accessor, and while digging I get pretty confused with the following behaviour:
class Item
def change_price
price=(2)
end
def price=(value)
#price = value
end
def price
#price
end
end
my_item = Item.new
p my_item.price
my_item.change_price
p my_item.price
=> nil
nil
I would expect the price to be set to 2. Clearly I totally misunderstood something that I thought obvious.
Would anybody be kind enough to explain me where I am being thick?
Thank you
Attribute setter (any function trailing with an equal sign) must be called on the explicit receiver. Otherwise, the local variable price is being created and assigned to the value.
Fix:
def change_price
# price=(2)
self.price=(2)
end

How to create a reference to a Ruby method so it can be executed later? [duplicate]

This question already has answers here:
How can I get a reference to a method?
(4 answers)
Closed 8 years ago.
I would like to do the following in Ruby:
Create a class with a method in it
1.5 Create an instance of the class
Create a reference to the method in the instance
Execute the method later
Something like this:
class Cat
def meow
puts "meow"
end
end
my_cat = Cat.new
portable_meow = my_cat.method("meow")
portable_meow.execute
# outputs "meow"
Instead of execute, which does not exist, use call.
portable_meow.call
Both of these solutions work. Thanks everyone for your prompt replies.
(Sorry, I really can't figure out how to get my code to format correctly below, but you get the idea.)
- Matt
class Catz
def meow
"meow"
end
end
my_cat = Catz.new
test = my_cat.method(:meow)
puts test.call
my_cat2 = Catz.new
test = my_cat2.method("meow")
puts test.call

What does a double colon do inside a module? [duplicate]

This question already has answers here:
What is Ruby's double-colon `::`?
(12 answers)
Closed 9 years ago.
I'm looking at the following code:
module Tag
def sync_taggings_counter
::Tag.find_each do |t|
# block here
end
end
end
and I'm confused by ::Tag inside the Tag module.
I know the double colon is used to name-space classes and modules within classes/modules. But I've never seen it used like the above. What does it mean exactly?
It's a scope modifier. Prefixing your constant (Tag) with a double colon ensures that you're looking in the root/global namespace instead of within your current module.
E.g.
module Foo
class Bar
def self.greet
"Hello from the Foo::Bar class"
end
end
class Baz
def self.scope_test
Bar.greet # Resolves to the Bar class within the Foo module.
::Bar.greet # Resolves to the global Bar class.
end
end
end
class Bar
def self.greet
"Hello from the Bar class"
end
end
The prepending is usually not neccessary as Ruby automatically looks in the global namespace, if it fails to find the referenced constant in the local module. So if no Bar existed in the Foo module, then Bar.greet and ::Bar.greet would do the exact same thing.

having multiple constructors in ruby [duplicate]

This question already has answers here:
In Ruby is there a way to overload the initialize constructor?
(7 answers)
Closed 9 years ago.
is there a way to have multiple “initialize” methods in ruby?
For example: one method excepting one argument while another excepts three ?
Something like
class One
def initialize (a)
puts a
end
def initialize_1 (a,b)
puts a ,b
end
end
initialize is actually not a constructor. You can indeed have two constructors.
class One
singletonclass.class_eval{alias old_new :new}
def self.new a
puts a
old_new
end
def self.new_1 a, b
puts a, b
old_new
end
end

Resources