Refer to method in module with same name as class
If you don't want to look up the constant relative to the current scope, just use an absolute path:
::Pushover.configure
Local variables and methods with the same name in Ruby?
In ruby you can have local variables and methods with the same name. This has some complications for example with setter methods in classes:
class Test
def active
@active
end
def active=(value)
@active = value
end
def make_active
active = true
end
end
t1 = Test.new
t1.active = true
t1.active #=> true
t2 = Test.new
t2.make_active
t2.active #=> nil
Code for t1 object will return expected result, but code for t2 returns nil, because make_active method is actually creating local variable and not calling active= method. You need to write self.active = true to make this work.
When you write gen_class, ruby tries to access local variable, if it is not defined ruby tries to call method. You can call your method explicit by writing gen_class().
method's local variable with same name as another method
I think that the local variable is declared as soon as it's enunciated. In ruby the lookup is first to look for a local variable, if it exists it's used, and if not it looks for a method. This would mean that val = val declares the first val as local and the left-hand val then matches it (not sure about it I should check the ruby under microscope to be sure)
If you try
class A
def val
10
end
def test
back = []
x = val
back << x
val = x + 1
back << val
x = val
back << x
end
end
p A.new.test
then all is good, it prints [10, 11, 11] which means the first x = val calls the method, the second calls the local variable, presumably.
Method and variable name is the same
Try this:
puts hello()
Class context overrides Module methods with the same name?
Class context overrides Module methods with the same name?
Yes, that is how it works.
class C
include M
end
makes M
the superclass of C
, that's all it does.
Since M
is the superclass of C
(or looking at it from the other side C
is a subclass of M
), methods defined in C
override methods defined in M
, that's just how inheritance works.
If you want M
's methods to override C
's, you need to use prepend which puts M
in front of the ancestors
list.
More precisely, an include class M′
is created whose class variable table pointer, constant table pointer, and method table pointer point to M
's class variable table, M
's constant table, and M
's method table. M′
's superclass pointer is set to C
's superclass, then C
's superclass pointer is set to M′
. The Object#class
and Class#superclass
methods know to "skip" singleton classes and include classes, and Module#ancestors
knows to return the corresponding module instead of the include class, so you don't see this working, but that's what happens.
This explains why methods defined in the class override methods defined in the included module. It also explains the behavior of super
with modules. It's all just straightforward class inheritance.
Rails associated models with a method of the same name
Firstly, ActiveRecord::Concern
can change a lot of behaviour and you've left out a lot of code, most crucially, I don't know where it's being injected, but I can make an educated guess.
For a Concern
's methods to be available a given object, it must be include
'd in the object's class's body.
If you have access to an instance of the Order
object, at any point you can call the balance
method:
order = Orders.last # grab the last order in your database
order.balance # this will call Order#balance
And if you have the Order
then you can also get the LineItem
:
order.line_items.first.balance # should call the Concerns:: LineItems::Aggregates#balance
You can open up a Rails console (with rails console
) and run the above code to see if it works as you expect. You'll need a working database to get meaningful orders and balances, and you might need to poke around to find a completed order, but Ruby is all about exploration and a REPL is the place to go.
I'd also grep
(or ag
or ack
) the codebase looking for calls to balance
maybe doing something like grep -r "(^|\s)\w+\.balance" *
, what you want to look for is the word before .balance
, that is the receiver of the "balance" message, if that receiver is an Order
object then it will call Order#balance
and if it is a LineItem
object then it will call Concerns:: LineItems::Aggregates#balance
instead.
I get the feeling you're not familiar with Ruby's paradigm, and if that's the case then an example might help.
Let's define two simple Ruby objects:
class Doorman
def greet
puts "Good day to you sir!"
end
end
class Bartender
def greet
puts "What are you drinking?"
end
end
Doorman
and Bartender
both have a greet
method, and which is called depends on the object we call greet
on.
# Here we instantiate one of each
a_doorman = Doorman.new
a_bartender = Bartender.new
a_doorman.greet # outputs "Good day to you sir!"
a_bartender.greet # outputs "What are you drinking?"
We're still using a method called greet
but the receiver is what determines which is called.
Ruby is a "message passing language" and each "method" is not a function but it's a message that is passed to an object and handled by that object.
References
- How to use concerns in Rails 4
- http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
- http://guides.rubyonrails.org/command_line.html#rails-console
Is it OK to use the same name for a Ruby method parameter and an accessor method?
It is totally safe to do this and I do it all the time. However, I think that's it's a better style to set your object attributes like this:
class Parser
attr_accessor :config, :html
def initialize(config, html)
self.config = config
self.html = html
end
...
end
When you do this, your code will use the setter methods provided by attr_acessor. This way you always have a consistent way that your variables are accessed.
Related Topics
Ruby Google_Drive Gem Oauth2 Saving
Scraping/Parsing Google Search Results in Ruby
Phonegap Mobile Rails Authentication (Devise? Authentication from Scratch)
Ruby Create Tar Ball in Chunks to Avoid Out of Memory Error
Rails Active Record: Find in Conjunction with :Order and :Group
Rspec 'Eq' VS 'Eql' in 'Expect' Tests
Pg::Invalidparametervalue: Error: Invalid Value for Parameter "Client_Min_Messages": "Panic"
Is There a Method to Limit/Clamp a Number
Making a Module Inherit from Another Module in Ruby
How to Specify a Read Timeout for a Net::Http::Post.New Request in Ruby 2
Documentation for Psych To_Yaml Options
Multiple Level Nesting in Yaml
Suppresing Output to Console with Ruby
Rails - Aciverecord Use :Dependent => :Destroy on Condition
Rails Initializes Extremely Slow on Ruby 1.9.1
Expected #Count to Have Changed by 1, But Was Not Given a Block