How to resolve ruby module/mixin method conflict
The problem for you is that there is no multiple inheritance in Ruby; so the modules get inserted as an ancestor one above the other, and as such F#initialize
overshadows E#initialize
. As you found, it is easy to access F#initialize
using super(f)
; but the other one needs a hack to access: we can pick the initialize
method directly off of the module, because it is an ancestor; then bind it to the current object and run it.
def initialize(e, f)
E.instance_method(:initialize).bind(self).call(e)
F.instance_method(:initialize).bind(self).call(f) # equivalent to super(f)
end
However, I do not recommend this. If you need to run several initialisers, you'd be better off using composition, rather than inheritance (and to be clear, include
is inheritance). ruby include method name collision
I assume the real question is: how do I ensure that the my modules are not using other modules methods, which (which accidentally have the same name).
It's best if you can make sure that your module methods are not state dependent and define them as module method and use them this way. So you explicitly use any helping
methods like this:
module C
def c
puts C.collision
end
def self.collision
'c'
end
end
module B
def b
puts B.collision
end
def self.collision
'b'
end
end
class A
include B
include C
end
A.new.b # b
A.new.c # c
If you want to make them private, there's some extra code to put there, you can read a clear article about it: https://6ftdan.com/allyourdev/2015/05/02/private-module-methods-in-ruby/As stated in this answer there's not magic you can turn on to make it work. Include mechanism is quite simple and (IMO) it should stay that way. As you are aware of this collision problem - you can now avoid it.
In case you don't like this approach, you can also encapsulate the real work in a class and use module just for inclusion:
module C
def c
MyLibStuff::ClassDoingRealWork.no_collision_here_anymore(any, param, if_needed)
end
end
In Dart, how can I call a superclass method shadowed by a mixin method?
The mixin method from C
shadows the method from B
, so you can't use super
directly to refer to the B
method. You need to introduce a way to access it.
What you can do is to put a private redirecting function in between the B
class and the C
mixin application:
class A extends B with _Helper, C {
int getValue() {
// It's C
super.getValue();
// Now I want to get B's getValue how do it?
return super._getValueFromB();
}
}
class B {
int getValue() {
return 1;
}
}
mixin C {
int getValue() {
return 2;
}
}
mixin _Helper on B {
int _getValueFromB() => super.getValue();
}
Since the mixin application order is B, B-with-_Helper, B-with-_Helper-with-C, the super
of the B-with-_Helper superclass is B
, and the _getValueFromB
will access it correctly. Ruby: Module, Mixins and Blocks confusing?
By the way: in Ruby 2.0, there are two features which help you with both your problems.
Module#prepend
prepends a mixin to the inheritance chain, so that methods defined in the mixin override methods defined in the module/class it is being mixed into.
Refinements allow lexically scoped monkeypatching.
Here they are in action (you can get a current build of YARV 2.0 via RVM or ruby-build easily):
module Sum
def sum(initial=0)
inject(initial, :+)
end
end
module ArrayWithSum
refine Array do
prepend Sum
end
end
class Foo
using ArrayWithSum
p [1, 2, 3].sum
# 6
end
p [1, 2, 3].sum
# NoMethodError: undefined method `sum' for [1, 2, 3]:Array
using ArrayWithSum
p [1, 2, 3].sum
# 6
Ruby mixins and calling super methods
You can use this:
super if defined?(super)
Here is an example:class A
end
class B < A
def t
super if defined?(super)
puts "Hi from B"
end
end
B.new.t
How can I call a function from a method of the same name?
A couple of different ways to resolve the name conflict:
As Christopher Moore mentioned, you can explicitly import
dart:core
with a prefix. Note that if you don't want to prefix everything fromdart:core
, you could import it twice, once into the global namespace and again into the prefixed namespace:
Then you would be able to explicitly useimport 'dart:core';
import 'dart:core' as core;core.print
within yourprint
method and useprint
normally everywhere else.Note that if you have a method trying to call a global function with the same name within the same Dart library, you could split your code into multiple files, or your library could import itself with a prefix:
foo.dart
:import 'foo.dart' as foo;
class SomeClass {
void f() => foo.f();
}
void f() {
// Do stuff.
}You alternatively could explicitly create another reference to the normal
print
function with a different name:final _print = print;
class A {
String val;
void print() {
_print(val);
}
}
How to mixin some class methods and some instance methods from a module in Ruby?
This pattern is very common in Ruby. So common, in fact, that ActiveSupport::Concern abstracts it a bit.
Your typical implementation looks like this:
module Foo
def self.included(other_mod)
other_mod.extend ClassMethods
end
def instance_method
end
module ClassMethods
def class_method
end
end
end
class Bar
include Foo
end
You can't accomplish this easily as you describe without somehow splitting the included module into multiple pieces, though, unfortunately. Mixins and duplicate methods in React.js
Yes, it's intentional, and the main factor that makes mixins very powerful in React.
So what happens is:
- for the 'component...' functions, they're called in the order of mixin[0], mixins[1], ..., component
propTypes
, and the return value ofgetInitialState
andgetDefaultProps
are merged- other conflicting method names, or conflicts while merging the above results in an error
Related Topics
How to Read Text from Non Visible Elements with Watir (Ruby)
Difference Between "Class A; Class B" and "Class A::B"
What Are Ruby's Numbered Global Variables
Binding to Networking Interfaces in Ruby
Dbi::Interfaceerror: Could Not Load Driver (Uninitialized Constant MySQL error)
Creating a Ruby on Rails Environment on Windows, in a Vm Vagrant Box
Best/Most Elegant Way to Share Objects Between a Stack of Rack Mounted Apps/Middlewares
How to Unescape C-Style Escape Sequences from Ruby
How to Implement Curry(Partial Function) in Ruby
Adding Bootstrap Icon to Button in Ruby on Rails
Why Does Including This Module Not Override a Dynamically-Generated Method
Unit Testing Code Which Gets Current Time
How to Flush HTML to The Wire in Sinatra