While I did not flag this entry is spam, I have flagged a lot of your past submissions. I’d like to try to explain to you why you get downvoted so much. These are only my opinions. Other people may have their own opinions. But I think you deserve at least an explanation of my reasoning.
There are two issues here: general and specific. The general issue is that these kinds of mainstream program tutorials aren’t on-topic at lobsters. While we’re a community focused on “computing”, there are some patterns to what people like to see here. Content that does well tends to be high-effort and informative, insightful, entertaining, or esoteric. There are already a lot of “introduction to Ruby” tutorials out there and they’re very easy to find, so they don’t do very well here.
(Compare our front page right now to the programming Reddit front page. You’ll see that there’s a lot more intro-to-programming tutorials and “learn Kotlin/FP/ML” stuff that does terribly here. Also a lot more content marketing by companies.)
That doesn’t mean that informative Ruby material is not wanted here, it just means that it has to be high-effort and aimed at experienced programmers. Here are some things that would be pretty highly upvoted here:
That’s the general part. The specific part, unfortunately, is that you have a poor reputation. The last 15 articles you authored were all downvoted as low-effort spam. This means that people are willing to cut you a lot less slack than they would others. So even a high effort post by you probably won’t be treated as well as the same post by anyone else. This isn’t unfixable: posting quality stuff you didn’t write and writing high-quality comments on other people’s submissions would go a long way to changing this reputation.
If you want to keep posting stuff you write: instead of 15 short low-effort pieces, write one comprehensive high-effort piece.
Nine of the past ten submissions you’ve authored have a score of 0 or less. Are you sure you understand what we’re looking for?
I produce content about programming and the job of developer..
There is 120 readers per submission. That’s what matters here. The majority over few “unhappy” developer.
Thank you for your “kind” feedback.
Cool article! Agree with the fact that we shouldn’t try to handle edges cases during the conception of a piece of software..
Didn’t you already post this eight months ago? We’re okay with repeats, but this is the first time I’ve seen an author repeat his own story.
It makes me worry you’re more interested in branding than contributing to the community. I’d appreciate if you posted other articles you didn’t write and commented on other people’s posts.
Thank you for your concern.
However, it takes time to write quality content (that’s my opinion). So it’s cool to update it and share it again when I learn new stuff about the article’s topic..
That’s what I did for this article. :-)
I hope you understand my approach.
Have you considered posting on other platforms? You seem pretty knowledgeable, but medium is absolute garbage.
Very similar article that seems to be easier to understand and read than this one.
The excellent pry gem which makes use of the binding instance is something every Ruby developer should be aware of.
Here we can see that we exclude the left value by omitting it in the range — starting by 91 instead of 90 in order to exclude the 90 value.
In which case, for which value of
surface the returning value will be different?
when 70..90 then :second_value - when (91..inf) then :third_value + when (90..inf) then :third_value
Same applies to the case with floats, isn’t
But, what if I want to exclude the left operand?
The cost of
next_float and intermittent ranges doesn’t seem to justify that desire.
Thanks you for your feedback !
Bundler use the same approach to evaluate
gemspecs file. And almost the same approach for the
So, as bundler is used thousands of times per day, then the practice doesn’t seems so dangerous.. hehe
The main point here is that I use eval in a safe context: reading a file that will be edited by the developers themselves.
It’s not an
eval in a controller action.
Don’t developers use gemfiles (and in this case, config files) written by unknown third parties (other developers) too, though? I don’t want to have to audit a config file for security.
Downloading code from the internet and then running it is a security vulnerability. It really is a wonder that most language specific package managers don’t trouble themselves with anything as sophisticated as an integrity check, let alone a signature, let alone any kind of sandboxing by default.
Ruby isn’t the only offender, in most languages, “bundler doesn’t work try running it with sudo, there you go” is standard operating procedure.
There are real package managers out there that attempt to tackle these problems and more (like guix), but they’re not the norm, and I don’t think any of them are perfect.
We considered this when building RubyGems, and in fact there was a competing ruby package manager at the time called RPA that tried to address these issues (https://github.com/threedaymonk/rpa-base). The problem is that for signatures to be meaningful, you have to establish a web of trust.
Since that’s a hard problem, and we were building a package manager from scratch at the back of a hotel bar at a programming conference so it could be demoed the next day, we decided to stick with what we could solve in an evening (and in any case installing a gem from rubygems.org is at least as secure as installing a tarball from the Ruby Application Archive, which is what we were hoping to replace (http://web.archive.org/web/*/http://raa.ruby-lang.org/)).
I still hope that one day someone will figure out a way for programmers to share code with each other with minimal friction, but also be able to trust the code that is being shared without accepting it on blind faith.
Having the gemspec be arbitrary Ruby code is a problem. Less so on the client and enduser (it runs most of the code downloaded from rubygems.org anyways, it doesn’t add much) than on the systems that actually need to digest them, like the rubygems host itself! AFAIK, for that reason, rubygems dumps the data it needs locally on the machine before publish. AFAIK also, the gemspec is not loaded on installation.
But that still means all tooling that wants to look at the gemspec (dependency update bots etc.) need to run it to get all the data out, especially because people do modify the gemspec to read external resources or similar.
There’s tons of problems coming out of that, which is why most second-generation bundlers don’t use code (interestingly, https://conan.io/ though uses Python for that).
The Gemfile being code is less so a problem, as it’s the code component that loads the dependencies in your app. It’s usually handwritten and frequently looked at. If I wanted to hide something, I’d hide it in a loaded dependency, as Ruby can evaluate arbitrary code during
Dangerous in which sense?
I will agree that
eval should generally be avoided, since it can accidentally clobber local variables. The code in the post does not uses
eval, however; it uses
If you mean dangerous in a security sense, then you are correct that you should not pass untrusted strings to
class_eval. If the string is from an untrusted source, it should be evaluated inside a sandbox. There are a number of libraries/gems that provide sandbox functionality, though I’m not sure which is the best to use these days.
Did the author not know about cloc?
Update page for this project: https://github.com/AlDanial/cloc
I also found this section in the intro documentation very graceful:
If cloc does not suit your needs here are other freely available counters to consider
I know this tool. But the purpose of the blogpost is to describe the
find library in Ruby.
The script is just here to illustrate a use case of this library. Nothing else.
Anyway, thank you for the tip. :-)
The eigen- prefix is used to describe something which is “the same” before and after a transformation. e.g. the eigenvector of a matrix is a vector which still points in the same direction after multiplying by the matrix (scaled by its eigenvalue). What exactly is the transformation going on here?
eigen comes from Germanic languages such as German and Dutch where it means own, particular to, etc.
Mijn eigen auto -> My own car.
Mijn eigenwaarde/eigendunk -> My self-esteem
So, the prefix eigen- does not imply a transformation. Though, I agree that it is confusing in CS to use this prefix, since non-native speakers immediately associate it with eigenvalues/vectors.
The term “singleton class” that the article briefly mentions is actually Ruby’s official term for this concept. Ruby’s standard library defines the
Object#singleton_class method; you can use
.singleton_class in place of
.eigenclass in all the article’s examples. Perhaps this potential confusion is the reason the Ruby team chose “singleton class” over “eigenclass”.
Thank you for your comment.
Eigen means “own” in German. So “eigenclass” means “owned class” (as this anonymous class is owned by its defined class).
Etymologically speaking, the “eigen-”-prefix was used by David Hilbert to describe that the value/vector is inherent to the thing. To confuse things a little, “eigen” is a pretty versatile word in german: https://www.dict.cc/?s=eigen
Hilbert probably used in the sense of “possessive”, “inherent”, “in-built”. In that sense, which is not focused on the transformation, “eigenclass” is rather similar.
(loosely taken and translated from: http://faql.de/etymologie.html#eigen)
I believe the ‘show’ tag is appropriate when posting your own blog.
Congrats on the blog and kudos to the dedication! I am personally really bad at blogging because I treat each post as an essay that has to perfectly and thoroughly convey my thoughts.
To me show is to show projects or things you’re done more than to indicate a self-posting. This is already an information displayed by “authored by” next to the Lobsters who posted the link.
Thanks for the tip about the tag.
It’s effectively hard to determine when your article is “ready”.
Due to duck typing design, Interface Segregation and Dependency Inversion principle are not relevant in Ruby.
Sorry, but I strongly disagree with you on this statement. I understand some ruby developers have an aversion to any type system or any formality, but being highly dependent on DT can cause you serious problems. Specially when you’re working with a large codebase, that has been around for a while and abuse on monkey patching.
Here are two good examples where these principles can be applied successfully in ruby and help you bring some sanity to your projects.
Thanks for your feedback.
But, this is not ISP.. The example doesn’t follow the principles:
This example show a
FeeCalculator that provides 2 methods..
ISP definitely does apply to Ruby, or any other language, because the principle in itself is not dependent on language constructs. It’s easier to visualize in statically typed languages because it’s explicit, it’s something you need to write. When working with dynamic languages, the construct doesn’t exist explicitly, but you’re still making design decisions about how the classes interact with each other. Understanding and reasoning about how much one class know about another in a given context, is exactly what ISP is about.
For example, in Ruby’s standard library, we have a File and a StringIO class. They each have their own methods, but they also share a smaller common interface. That is not accidental, the library designers made a conscious decision to have similar methods so that the class can be used interchangeably in specific contexts.
As a user of those libraries, you also have an option. You can use methods on those classes that are specific to each one, or you can organize your code in a way where you pick a very small interface that you’re gonna depend on. If you only use methods that are available on both classes, you can pass any of those classes into your component and it will just work.
The main difference on dynamic languages is that you don’t have a fixed set of interfaces that are provided by the library authors. You have a number of interfaces that is equal to the combination of all methods available in that class API.
My thought is that “duck typing” in Ruby is merely a consequence of object polymorphism. Like Smalltalk that so influenced it, Ruby allows requests (messages) to be sent to an object which might handle them or not. For example, one might have a collection of objects and request that each “fly”. Whether they can or not is determined at runtime.
So I contend that it doesn’t “encourage it”. Rather “duck typing” in this context is a name indicative of how object polymophism in Ruby is achieved.
“Duck Typing” is just interfaces without the type system.
An interface is a set of methods implemented by an object. An object can be explicitly declared as fulfilling an interface (like in Java) or it can be implicit if the object implements all off the interface’s methods (structural typing, like in Go).
The problem with doing this with dynamic languages is, of course, that you won’t know if your object correctly implements all of the interface until runtime. Worse, with “Duck Typing”, there is no formal definition of the protocol that you can check, even at runtime.
In SmallTalk, interfaces are called “protocols” (in fact that’s the name I typically use to talk about that concept, even though I include a little bit more in the notion that just the interface, but I digress). The fact that protocols are not formalized in SmallTalk is not a design choice, see Future Work here:
[In Smalltalk-80] message protocols have not been formalized. The organization provides for protocols, but it is currently only a matter of style for protocols to be consistent from one class to another. This can be remedied easily by providing proper protocol objects that can be consistently shared. This will then allow formal typing of variables by protocol without losing the advantages of polymorphism.
Incidentally, it looks like Pharo did formalize protocols.
This is not to say that using Duck Typing in languages that provide no typed option for structural typing is bad, but a little more formalism and safety cannot hurt in that respect.
Ruby - the project and community - does encourage it, through it’s use in the stdlib and in general practice.
Interestingly, this hasn’t always been the case, the push towards making Ruby a duck-typing ecosystem and adopting it as a strategy was with 1.8, shortly before Rails. See https://viewsourcecode.org/why/hacking/rubyOneEightOh.html, “Duck typing and to_str”
Also, I feel that it’s natural to use duck typing in the context of a dynamically typed & fully object-oriented language such as Ruby.
You do a decent job of using the phrase “alias keyword” however I notice the heading for that section is labeled “the alias method” (it’s not a method as you correctly state otherwise).
I think a phrase that is potentially missing is “lexical scope”
Oh sorry for the typo hehe.
Yep, I explain what’s a lexical scope without explicitly naming it.
I gonna update my post. Thanks for your feedback ;-)
There is a
public_send method that respects method visibility - to be completely honest I’m not sure how it deals with protected status, though, since protected is not typically seen in idiomatic Ruby afaict.
I do like the perspective of looking at method dispatch in terms of sending messages, though. Decent write up!
public_send does not call protected methods. And, yeah, protected rarely happens in Ruby. I consider it a mild code smell as it implies the use of inheritance.
And, yeah, protected rarely happens in Ruby. I consider it a mild code smell as it implies the use of inheritance.
I’ve always considered
private to be the wrong choice, in any language, because it signals that I think I know every way anyone might ever want to extend my class. Inheritance may not always (or even often) be the right solution, but making certain extension options impossible is just going to drive future coders crazy.
private to lower the cost for future internal refactors, and upgrades, by providing a signal that “Hey, this method is not part of the public API, I do not condone its external use, and reserve the right to change it wildly.”
It communicates that there consciously was no consideration for what might happen if external objects began to depend on said private method. Later changes by anyone (not just the original author) can and will be free to change the private method at will: refactor, upgrade, remove entirely, and there is less to hold in your head and worry about when upgrading them later.
However, behavior of a private method that is observable through the a public method is fair game, and test cases should exist for those. The flip side of this is that, except in some rare cases, I favor not testing private methods. Any behavior that is possible via a private method, but which cannot be exercised or observed through use of public methods, should not be considered as supported behavior on the object. That does not preclude a new public method from exposing more of the private method’s behavior later, but at that point it is part of the public interface, and should be presented and documented as such.
As for making certain extension options impossible, at least in the context of Ruby, private does not do this.
class PrivateGreeter private def greeting "Hello." end end class PublicGreeter < PrivateGreeter def speak greeting end end
irb> PrivateGreeter.new.greeting # => NoMethodError: private method `greeting' called for #<PrivateGreeter> irb> PublicGreeter.new.speak # => "Hello."
You can even give it the same name as the parent class’ private method if you really, truly need to let external objects utilize the method as part of the subclass’ public API with the exact same name:
class PublicGreeter < PrivateGreeter def greeting super end end
irb> PrivateGreeter.new.greeting # => NoMethodError: private method `greeting' called for #<PrivateGreeter> irb> PublicGreeter.new.greeting # => "Hello."
Since an inherited class can make use of its parent class’ private method, the question then becomes: should it? If we have a stipulation that the parent class reserves the right to refactor its private methods or change them wildly, should we rely on a parent class’ private method?
I think the answer differs between application code and library code. If the parent class comes from a library, or some internal, but still cross-domain, utility code, I would not want to rely on the existence, the arity, or the behavior of a private method. If the behavior is so critical, I would rather capture the behavior permanently as part of the subclass by copying the code itself over to the subclass (or not use inheritance at all, but I would still definitely copy the code). Everything I have seen makes me agree that duplication is far cheaper than the wrong abstraction.
In the case of application code, it is more acceptable to rely on a parent class’ internals. I still would fight the urge, but it can be expected that the author modifying the subclass and parent class has access and authority to work on both in order to get their job done, that the tests for both classes live in the same suite, and other niceties that make maintaining that dependency across time situation more tenable.
Just -3? I’m disappointed!