OK, I think an app this simple doesn't need funding, specially in a world where people die of starvation and malaria. Yet all I get for my observation is downvotes.
You didn't mention that you thought the app was simple. You said you thought running crowdfunding for it was dishonest and immoral.
In any case... Parsing 35TB of HTML, JavaScript and images, and then releasing that as structured data, on top of rebuilding a sustainable web service? I don't think it is simple at all. It's not exactly a hackathon project.
I think we can debate that point, but what I can't understand is the reason behind the downvotes. Downvoting prevents the debate entirely, and I find it unreasonable.
Your first comment said "I find it dishonest and immoral". You should have followed that sentence with some explanation about why you felt it was dishonest or immoral. Perhaps you don't realise just how offensive that sentence is?
Some of your later comments say something along the lines of "why pay money for this when people are starving?" Well, you can apply that to everything. What computer are you using right now? Why didn't you buy a €30 raspberry pi and donate the rest to a clean water charity?
Interesting innovative ideas or discussion about developin world problems do get upvotes. Merely saying "why spend on this instead of starving children" will allost always get downvotes because it's not an interesting discussion.
Nobody asked for an argument, and by downvoting any argument on my part was prevented. I can explain why I find it immoral: I think the world has many real and deep problems, and investing in a web application that is not hard to build and solves a superfluous first world problem, is a waste of resources. Conversely, I think profiting from it is dishonest and immoral. You may disagree with my reasoning and you may have a different world view to compare, but the downvotes just terminate the conversation.
> Nobody asked for an argument, and by downvoting any
> argument on my part was prevented.
I feel like we're all being trolled, but how is your failure to present a cogent argument in your initial comment affected by downvotes that occur at a later time? You did the online equivalent to walking up to someone and saying to their face that they are dishonest and immoral, without any rationale for such an offensive position. In real life, you'd be punched in the face or, at the very least, escorted off their property. Is the fact that you're being downvoted really that surprising to you?
What you write is being held to a higher standard than what you are accustomed to. You can choose to use this as an opportunity to grow and improve your writing and better present your thoughts or you can choose to complain at how unfair it is. In your Redis comment[0] you talk about having manners and respect for other people's work. Perhaps you can hold yourself to this same standard.
Can you show an example of what you are describing? It doesn't sound interesting for the tasks I have in mind, so it must be the case that you are dealing with very complex tasks.
You have probably seen code written by the best programmers you know, and I guess you are comparing their work with the code in open source projects. As the rest of us can't see their code, it's impossible to agree with you, so we can only trust you blindly. But "trust" with something so technical is a bad criteria, and that's why open source software is good for showing your approach to problem solving and your programming style.
I think the idea of "doing open source work" sounds a bit disproportionate. At least to me. Instead, think about people sharing some small tools they have built for themselves. Even if they work for IBM, they should be able to customize their environment by tweaking some tool or writing a script to make their lives easier. They only have to share that code, not to show off but to help others with similar problems.
I think it is a matter of perspective. People still die of starvation and lack basic health care, there are still slaves in the world, and you are devastated for reasons that are absurd. Take a look at this picture:
This is actually a very complicated way of achieving the goal. It works, but it's not good from an economic point of view as it is more expensive in computational terms than a simpler OO alternative, which is to pass the size when you instantiate the MegaLotto::Drawing object.
For example, compare the proposed solution:
MegaLotto.configure do |config|
config.drawing_count = 10
end
MegaLotto::Drawing.new.draw
With the alternative:
MegaLotto::Drawing.new(10).draw
If you want to make it extensible, you can use keyword arguments:
MegaLotto::Drawing.new(size: 10).draw
The interface and the implementation are simpler, but also the performance is better because there are less method calls. If you look at the code of both implementations, you will find the simpler one easier to understand. As a side effect, you will also get simpler stack traces if anything goes wrong.
Right...but even in this trivial gem, there may be the need to configure more than one parameter. And by having Configuration be it's own object, you can encode some validation logic at the configuration stage.
I do agree that the constructor should have the option of passing in a Hash, which is then passed directly to the Configuration option.
Another problem with the approach from the blog post is locality. If you need to draw 10 numbers in all places, then configuring that value in the module will work. But localy, when you look at the code, it won't tell you how many numbers you are drawing.
If you have this in many different places:
MegaLotto::Drawing.new.draw
You don't have the information of how many numbers you are getting back. That's not a big deal, but adds to the cognitive load (or requires some comments). Also, if you need to draw different numbers in several different places, you will have to change the configuration many times:
# First use, we need 10 numbers
MegaLotto.configure do |config|
config.drawing_count = 10
end
MegaLotto::Drawing.new.draw
# Second use, we need 6 numbers
MegaLotto.configure do |config|
config.drawing_count = 6
end
MegaLotto::Drawing.new.draw
And as soon as you do that, you may need to take multi-threading into account, because you are mutating the class.
Extrapolating, it is like defining the size of an array:
Array.new(4)
If instead you configure Array.new to have a given size for all instantiations, you also lose locality and you may run into thread safety issues.
In the case of MegaLotto::Drawing.new needing multiple configuration options, you can use keyword arguments. If you need too many arguments, maybe the abstraction is wrong. Even if you want to move forward with too many arguments, you can add getters/setters to the newly created instance:
# Another approach which modifies the instance
drawing = MegaLotto::Drawing.new
drawing.size = 10
drawing.draw #=> returns ten numbers
But this is not optimal design given the elements we have.
Ah yes, mutating the class is most definitely a concern...which is why I give you an additional +1 for advocating for a Hash to be passed into the constructor.
This seems to be what the Twitter gem did too, in its newest versions. AFAIK, the Twitter configuration was a mutation to the class via config object, and now it's been revised to be thread safe:
A setting maybe needed per app, per process, per thread, per class|module, per subclass|include/extended module, per instance or per method call. (Phew.) And that's probably only 90% of use-cases, not counting apps configured by something like a JSON api, ZooKeeper or Chef databags.
The trick is to isolate config from behavior out of code as much as possible, scala style. An obvious example is to use environment variables so apps can be reconfigured without touching code.
In this case you are probably right. The solution with separate configuration shines though, when you have many values to configure (notwithstanding keyword args). But, and that is my main takeaway, TDD does apparently (and not surprisingly) not show the way to one or the other solution. On the contrary: the solution was already given in advance and the TDD part was more or less toying around with the moving parts of the solution.
I think it's bad manners to act like if the author owed you something. Redis is a monumental personal effort, and a lot of people try to help in many different ways because they are grateful such a tool exists. If you want to improve Redis, you are welcome to discuss any issue and even provide a patch, but you have to be respectful. A comment like yours is very demoralizing for open source contributors.