I usually see this in code:
class MyBotClient(commands.Bot):
async def on_ready()....
client = MyBotClient()
But I always do this in my code:
client = commands.Bot(command_prefix=....)
What is the difference between these two methods, and is there any advantage of either of them?
Customizability, Maintainability and Code Cleanliness
The difference is mainly customizability, maintainability and code cleanliness.
Code Cleanliness
I had like 10 variables that are an attribute of client, e.g.
bot = commands.Bot(...)
bot.x = ""
bot.y = 1
bot.z = 0.2
# and so on to like 10 lines...
when I created my own class, I put it in another file and the class is like
class MyBot(commands.Bot):
def __init__(self, *args, **kwargs):
self.x = ""
self.y = 1
self.z = 0.2
# and so on...
Now my main file just cleanly creates the bot and runs it, simple, but this is mainly because it's open-source
Customizability
Subclassing allows you to extend, expand, and even diminish, or
degrade, the existing functions and coroutines. Perhaps to add extra
validation of parameters, perform additional processing to the
original function, or even to change the purpose of the function or
coroutine altogether.
From What Are the Benefits of Subclassing (Visual Basic)
You can add/change so much with a subclassed bot, for example, you can make a custom context class that is returned instead of the usual commands.Context, this would allow you to add custom functions/attributes to even the context. One of the things I did is that I overrode the send method of my custom context so that it replies to the user on every command
Maintainability
This kinda falls under code cleanliness as it makes the code easier to maintain/change in the future. Like all your events can stay in one place, and even in my example before, I had like 140 commands at the time, I wanted the bot to switch to the new discord reply system, I didn't need to replace ctx.send with ctx.reply everywhere in each file, I just overrode the send to use reply unless it's explicitly disallowed
Related
I've been reading Sandi Metz's Practical Object-Oriented Design in Ruby and many sites online discussing design in Ruby. Something I've had a hard time fully understanding is the proper way to implement dependency injection.
The internet is flooded with blog posts that explain how dependency injection works in what I think is a very partial way.
I understand that this is supposed to be bad:
class ThisClass
def initialize
#another_class = AnotherClass.new
end
end
While this is a solution:
class ThisClass
def initialize(another_class)
#another_class = another_class
end
end
And that I could send the AnotherClass.new like this:
this_class = ThisClass.new(AnotherClass.new)
That is the approach that Sandi Metz recommends at least. What I don't understand is where should a line like that go? It has to go somewhere and generally in examples of this what's shown is a line like that being placed totally outside of any class, method, or module as if I'm simply entering it all by hand in IRB for testing purposes.
This post (among others) suggests this different approach:
class ThisClass
def another_class
#another_class ||= AnotherClass.new
end
end
Jamis Buck would take a similar approach like this:
class AnotherClass
end
class ThisClass
def another_class_factory(class_name = AnotherClass)
class_name.new
end
end
However, these two examples both preserve AnotherClass's name inside ThisClass, which Sandi Metz says is one of the main things we're trying to avoid.
So what is the best practice for doing this? Should I make a 'dependency' module filled with methods that are factories for objects of each class in my application?
Something I've had a hard time fully understanding is the proper way to implement dependency injection.
I think the best definition of a "proper" implementation is one that adheres to the SOLID principles of object oriented design. In this case mostly the Dependency Inversion Principle.
In this regard, this is the only presented solution that does not violate the DIP(1):
class ThisClass
def initialize(another_class)
#another_class = another_class
end
end
In all other cases, ThisClass has a hard dependency on AnotherClass, and can not function without it. Furthermore, if we wish to replace AnotherClass with a third, we need to modify ThisClass, which is a violation of the Open Closed Principle.
Of course, in the example above, naming the parameter and instance variable another_class is not ideal, since we do not now (and do not need to know) what object is passed to us, as long as it responds to the expected interface. This is the beauty of polymorphism.
Consider the below example, taken from this ThoughtBot video on DIP:
class Copier
def initialize(reader, writer)
#reader = reader
#writer = writer
end
def copy
#writer.write(#reader.read_until_eof)
end
end
Here you can pass any reader and writer objects that respond to read_until_eof and write respectively. This gives you full freedom to compose your business logic using different pairs of read and write implementations, even at runtime:
Copier.new(KeyboardReader.new, Printer.new)
Copier.new(KeyboardReader.new, NetworkPrinter.new)
Which brings us to your next question.
It has to go somewhere and generally in examples of this what's shown is a line like that being placed totally outside of any class, method, or module [...]
You are correct. While object thinking involves modelling the domain with well isolated, decoupled, and composable objects, you will still need to define how these objects interact, in order to implement any business logic. After all, having composable objects is no good unless we compose them.
The analogy that is often made here is to think of your objects as actors. You are the director, and you still need to create a script(2) for the actors to know how to interact with each other.
That is, you need an entry point into your application. A place where the script starts. This might itself be an object--normally an abstract one. In a command line application, it can be your classic Main class, and in a Rails application it can be your controller.
This might seem strange at first, because the focus of object thinking is on modelling concrete domain objects, and a great deal of all writings on the subject is dedicated to this effort, but just remember the actor-script metaphor, and you'll be on your way.
I strongly recommend you pick up the book Object Thinking. It does a great job explaining the mindset behind object oriented design, without which knowing the language specific implementation details becomes rather futile.
(1): It is worth noting that some proponents consider storing an instance of another class in an instance variable an anti-pattern, but in Ruby, this is fairly idiomatic.
(2): I am not sure if this is the origin of the term script in programming in general, but maybe some historian can shed some light on this.
Thanks to some other posts and reading, I understand singleton/meta classes. And I understand why we'd want to use them on a class. But I still don't understand why we'd want to use them on instance objects. And I've yet to see it in practice.
I'm referring to something like this:
class Vehicle
def odometer_reading
# some code
end
end
my_car = Vehicle.new
def my_car.open_door
# some code
end
At first thought, this seems like a bad idea as it would lead to difficulties in understanding the code and debugging.
Why would we want to do this? What are some examples of when this is a good idea?
One example is using it for testing purposes: creating mock and double objects, stubbing methods. Debugging is somewhere nearby: re-defining the logging method for a specific object that you suspect is mis-behaving, so that the log info is printed directly to console (or more info is printed) during the debug session.
Another example is dealing with special cases - instead of inheritance you can do just that. Starting from a classical example if you use two types of Employees, say, Engineers and SalesPersons, for which the rules of compensation calculation are different, you can put the common logic into the Employee class, then inherit the other two classes from it and implement their own calculate_salary methods there. Now, if there is an outlier - a star salesman that you have agreed to a different compensation scheme with, a CEO with a very special scheme, etc - instead of creating a whole sub-class for this special employee, you can just define this method for a specific object representing that employee.
The third example is dealing with an object lifecycle and performance considerations. Instead of having a long case of various states in some processing method. E.g. for a file-reading class that transparently caches the entire file in the background (I know a too-simplistic-for-real-life approach, but just as a model) all read requests while the file is not entirely read should check if the requested data is already in the cache or should be read from disk. Once the file is fully read they always go from the cache. Instead of having the if (case if there are more states) to deal with this you could simply re-define the read method at the object-level once the file is fully read to the cache. For this simple example it doesn't lead to any sizable performance benefit (if any benefit at all), but for more complex cases that may be worth it.
You wouldn't add them using def, that's a rather rigid way of doing it, but instead by using something like define_method or extend.
Although this is not the sort of thing you'd do on a routine basis, it does mean you can do some rather unusual things. ActiveRecord in Rails produces results in the form of an Array with additional methods added on to perform other operations.
An Object-Relationship Mapper would be a case where you'd probably want to do this. Sometimes, depending on how you fetch a record, the methods available differ significantly. Being able to add those dynamically means each fetched object can be completely customized even if they have the same class and general-purpose methods.
Another example: You have an array of hashes and you want each hash to have a method-call getter and setter. Something like:
user = HashOnSteroids.new(name: 'John')
user[:name] # => 'John'
user[:name] = 'Joe'
user.name # => 'Joe'
user.name = 'John'
user.set(name: 'Jim', age: 5)
This means you cannot write standard method definitions in the class as each hash will have a different set of keys (method names). This means you have to resort to defining singleton methods so each object has its own set of methods (not a pack of shared methods).
Warning: Using singleton methods for this use case is highly inefficient. A sneaky method_missing is faster and uses way less memory as it doesn't have to allocate a billion of proc objects.
I'm trying to write a short class to represent an object stored on a remote server. I expect setting attributes of the object locally without setting them on the remote server will generally be a bad idea; it'll mean the local object no longer represents the remote one, without even being aware of that fact.
I had planned on using code like the below to handle this. It lets you shoot yourself in the foot if you want to set item.name, but assumes users will be sensible and not do so.
class Item(object):
def __init__(self):
self.name = get_item_name()
def set_name(self, name):
try:
set_item_name(name)
except:
handle_error()
raise
else:
self.name = name
However, I recently came across the #property decorator, which let me write the below:
class Item(object):
def __init__(self):
self._name = get_item_name()
#property
def name(self):
return self._name
#name.setter
def name(self, value):
try:
set_item_name(value)
except:
handle_error()
raise
else:
self._name = value
This has the advantage of still allowing attribute access using item.name, but also handling item.name = blah assignment.
However, while the second block of code offers (what seems to me to be) nicer behaviour, it hides a function call in attribute setting, and given the Zen's "Explicit is better than implicit" and the general idea that Python classes should not hide things from their users, does this make the second block of code less Pythonic?
Writing code in OO languages is all about hiding things. When you write a method doSomethingComplex(), you basically create a new word in the language of your application which hides some complex operation from the developer who has to use the method.
While explicit is usually better than implicit that doesn't mean always. In your case, the problem is not in hiding the method call in the setter but in the fact that you're hiding the network. As soon as you try to hide the real, physical network from the user of a method, you need to make sure you handle the following cases correctly:
The remote side suddenly dies
The network drops packets (timeout on local side)
The remote side throws an exception (you must somehow get it to the local code but it might be meaningless locally)
The remote side successfully processes the call but the network drops the answer (so you did succeed but you don't know)
No matter how hard you try, this hidden complexity will leak through. As a simple example, developers using this code will have to handle network exceptions and timeouts (as opposed to any other method).
So the break here is less that you call a method in a setter but that you introduce a completely new contract.
What is a better solution? Make the network call explicit. That means more obvious effort for users of the code but they will always know what they're up against (instead of wondering why this setter behaves so oddly).
Suggested implementation: Use the command pattern to modify the state of these objects. The command needs the ID of the object to modify (so you don't have to keep a local copy), the field to change and the new value.
Update the local cached copy when the remote side replies "success". If the remote side returns an error, drop the cached copy so it gets fetched again.
This will create a lot more code but this code will be pretty simple and obvious. When you try to hide the remote side, you will have less code but it will be more complex and obscure.
PS: Never assume that people are sensible over an extended period of time.
I'm trying to write a GUI in PyQt that has a network layer which should notify the GUI of any new messages that are received over the network. In C#, I would have written a delegate/event pair in my net class:
//event handler for propagating new message to GUI
public delegate void MessageReceived(String from, String msg);
public event MessageReceived messageReceived;
This way, all the GUI needs is a reference to the messageReceived variable (and the net class remains agnostic).
Now, I've read all about signals and slots in PyQt, but I haven't been able to find anything that explains how to replicate the above functionality. Any ideas?
I've only recently learned to appreciate the awesomeness of SIGNAL(), and it's not too complicated.
You'd want to create a new class that is threaded:
class NetworkThing(QtCore.QThread):
def __init__(self, parent = None):
super(NetworkThing, self).__init__(parent)
def run(self):
while True:
time.wait(1.0)
# Do your background stuff, and then emit:
self.emit(QtCore.SIGNAL('messageRecieved(QString)'), 'The response text.')
From within your main application initialization function, you need to prepare a new variable and a new SIGNAL() catcher:
self.networkThing = NetworkThing()
self.connect(self.networkThing, QtCore.SIGNAL('messageRecieved(QString)'), self.processEvent)
Now, the response of the networking thread it piped instantly to the function processEvent().
Just as a side note, the run() function of NetworkThing() is automatically run by PyQt4, so there is rarely a time when you manually call it. Instead, call self.networkThing.start().
If you want to look at a pretty nice example of this stuff, read this article: http://diotavelli.net/PyQtWiki/Threading,_Signals_and_Slots.
I am designing a class for log entries of my mail server. I have parsed the log entries and created the class hierarchy. Now I need to save the in memory representation to the disk. I need to save it to multiple destinations like mysql and disk files. I am at a loss to find out the proper way to design the persistence mechanism. The challenges are:
How to pass persistence
initialization information like
filename, db connection parameters
passed to them. The options I can
think of are all ugly for eg:
1.1 Constructor: it becomes ugly as I
add more persistence.
1.2 Method: Object.mysql_params(" "),
again butt ugly
"Correct" method name to call each
persistance mechanism: eg:
Object.save_mysql, Object.save_file,
or Object.save (mysql) and
Object.save(file)
I am sure there is some pattern to solve this particular problem. I am using ruby as my language, with out any rails, ie pure ruby code. Any clue is much welcome.
raj
Personally I'd break things out a bit - the object representing a log entry really shouldn't be worrying about how it should save it, so I'd probably create a MySQLObjectStore, and FileObjectStore, which you can configure separately, and gets passed the object to save. You could give your Object class a class variable which contains the store type, to be called on save.
class Object
cattr_accessor :store
def save
##store.save(self)
end
end
class MySQLObjectStore
def initialize(connection_string)
# Connect to DB etc...
end
def save(obj)
# Write to database
end
end
store = MySQLObjectStore.new("user:password#localhost/database")
Object.store = store
obj = Object.new(foo)
obj.save
Unless I completely misunstood your question, I would recommend using the Strategy pattern. Instead of having this one class try to write to all of those different sources, delegate that responsibility to another class. Have a bunch of LogWriter classes, each one with the responsibility of persiting the object to a particular data store. So you might have a MySqlLogWriter, FileLogWriter, etc.
Each one of these objects can be instantiated on their own and then the persitence object can be passed to it:
lw = FileLogWriter.new "log_file.txt"
lw.Write(log)
You really should separate your concerns here. The message and the way the message is saved are two separate things. In fact, in many cases, it would also be more efficient not to open a new mysql connection or new file pointer for every message.
I would create a Saver class, extended by FileSaver and MysqlSaver, each of which have a save method, which is passed your message. The saver is responsible for pulling out the parts of the message that apply and saving them to the medium it's responsible for.