How to override method in installed package in django rest framework? - django-rest-framework

I have installed django_cognito_jwt using pip. The package has two modules backend.py and validator.py and one init.py file. I want to overridea method of a class SampleClass in validator.py. I created a file in my django rest app called authentication.py. Then I called the class
from django_cognito_jwt import SampleClass
CustomSampleClass(SampleClass):
def methodA(self):
do something
return value
I used the exact same name of the parent method with the same arguments. But the call flow does not reach the extended class. Why??

Inherit from the desired django_cognito_jwt class within your class.
In your class, override a method with the same name as the method you want to override.
And use the class you made wherever you want

Related

Using self in modules

Is there a difference between the following two examples? Is it possible to get method conflicts in the second example because of method names? Aren't methods within a module automatically "encapsulated" within this module?
Example 1
module ImageUtils
def self.preview(image)
#do something
end
end
Example 2
module ImageUtils
def preview(image)
#do something
end
end
If I would put everything into a class Foo within the module ImageUtils, how would this differ?
The difference is that first example defines module method called preview, and second example defines mixin method preview.
So that if you include first module into a class, you'll be able to call this method on the class (whereas calling the method on the class instance would cause the error), while including the second module into the class will allow you to call the method on class' instances, but calling the method on the class itself will cause
NoMethodError: undefined method preview for Foo:Class
Regarding conflicts basing on the same method name in class and module included to it. Answer to this question lays in Ruby method lookup, which is following:
Methods from the object's singleton/meta/eigen class
Methods from prepended modules (Ruby 2.0+ feature)
Methods from the object's class
Methods from included modules
Methods from the class hierarchy (superclass and its ancestors)
Method lookup stops, when the method is found.
With prepend the mixin method will have precedence in method lookup;
With include method defined in class has the precedence in method lookup.
So no conflicts are possible.

Ruby/rspec not recognizing Ruby class with the same name as a former module

I have a ruby class, Feedbin, that was previously the name of a module. When I try and call any methods in the class, a TypeError is thrown: `': Feedbin is not a class (TypeError)
When I change the name of the class, but appending an s for example, things seem to work as expected.
The same program used to have a module named Feedbin as well, but the module no longer exists.
Old:
module Feedbin
class Api
end
end
New:
class Feedbin
end
How can I get rid of the "Feedbin is not a class" type error? What is causing this?
A non-class module cannot be changed into a class. Once you define a (non-class) module, it cannot be changed into a class. You perhaps have:
class Feedbin
...
somewhere prior to where you have
module Feedbin
...
Change that class into module, or use a different name instead of Feedbin for one of those.
Or, does the error message occur for certain methods? Certain methods can be defined on classes only. For example, if you call Feedbin.new, or something that calls initialize on Feedbin, and change Feedbin into a non-class module, then that would cause an error. In such case, use a different name for the non-class module.
Just had the same problem when running via web server.
The solution was to restart the server.

Ruby method overriding in rails app

I got a few Classes that include the same module, I want to override one of the methods of the module in one place in my code.
How to do this?
I tried
module [Module_name]
def [method_to_override]
and add it to the autoload path of rails but no success
If you are using the module as a mixin, you can redefine the method in your class. The method defined at the class level will take precedence when called. The module as a mixin simply behaves as a superclass in this case.
If you are using the module as a namespace, I am not sure that there's a way to dynamically redefine the code as you are attempting to do. Perhaps opening the namespaced module in-place and including the new code for the method will work. I haven't tried this before.
Some reference material

Ruby reopening classes -- can overridden methods be accessed?

I know if I subclass the String class and override its capitalize method, I can call the String class' version of capitalize with super. What if instead I reopened the String class and rewrote the capitalize method? Is there a way I can call the previous version of that method?
Not out of the box. A common approach is to rename the existing method to a new name. Then, in your rewritten version, call the old method by the new name.
def String
alias to_i old_to_i
def to_i
#add your own functionality here
old_to_i
end
end
You might also want to look at alias_method_chain, which does some of this for you.
There is also another interesting approach to get super working - if the class to open supports it (e.g. because it's written by yourself):
The methods of the class are not directly defined in the class body, but in another module that is then included. To overwrite a method of the re-opened class, include your own module with the extend version of it (which might use super).
This is, for example, used in the irb-alternative ripl to let plugins implement their own versions of core methods (which call super to get the original behaviour).

main vs initialize in Ruby

Okay, so I've looked through a couple of my ruby books and done some googling to no avail.
What is the difference between main and initialize in Ruby? I've seen code that uses
class Blahblah
def main
# some logic here
end
# more methods...
end
and then calls it using Blahblah.new.
Isn't new reserved only for
initialize? if not, then what's the difference between the two?
Class#new calls alloc on the class and then initialize on the created object. It does not call main.
The method name main has no special meaning in ruby's standard library. So unless you're inheriting from a class, which defines new or initialize in such a way, that main will be called, main will not be called automatically in any way.
See class Class
Look up class Class in your Ruby documentation.
You will find a public instance method called new.
All classes are instances of Class, so they all have a class method self.new. As it happens, this method calls allocate to create the class and then, if an initialize instance method is defined for the new class, it calls it, and forwards its (i.e., new's) arguments.
There isn't anything special about main.

Resources