How do I write a Date transform method? - ruby

It's very simple. Here's what I want to do with a date that is formatted as YYYYMMDD:
month = datestring[0:2]
day = datestring[2:2]
year = datestring[4:4]
return "#{month}/#{day}/#{year}"
The problem is, and I've never understood this about Ruby, do I do:
a module?
a mixin?
something else?
I know what I want to do, I just have NO idea what kind of file or structure to put it in. And if it's a module, do I prefix the method name with the name of the module:
module DateHelper
def DateHelper.transform(datestring)
...
end
end
Why or why wouldn't I do this? Thanks a lot for helping to clear something up that's represented a mental block for me.

Instead of modules, consider using objects with composition:
class DateString
def initialize(date)
#date_string = date
end
def format
...
end
end
Now you can do:
my_date_string = DateString.new("20121203")
puts my_date_string.format # => "12/03/2012"
This answer covers the ruby-philosophical part of your question, but if you're doing a lot of date formatting, consider using a gem that already does it for you.

The code in your question is suggestive of a mixin, which is one possible way to go. It is more idiomatically written like this:
module DateHelper
def date_to_some_format(date)
...
end
end
Notice that the method is an instance method, and that it has a name that won't potentially clash with other methods in an arbitrary class. If you wanted the method available at the class-level, one way you could do this would be:
class SomeClass
class << self
include DateHelper
...
end
end
That is one way to handle class-level mixins; there are others as well.
Whether you want a mixin will depend upon the context. Does the date formatting involve code that you find repeating all over the place in unrelated classes? Is it a one-off that you will never use again? Is remembering state required? Is the date format so useful it might be made into an extension to a core library? The answer to these questions will suggest whether the code should be handled in a mixin or in some other way. (Mixins are generally implemented in Ruby with modules.) Part of really learning ruby is getting a sense of the answers to these questions in different contexts; there are few simple answers in this regard, and to a certain extent things depend upon convention, personal preference and house style.
As an aside, one way to get the date format you're looking for is this (following your input date format of YYYYMMDD):
Date.strptime("20100101", "%Y%m%d").strftime("%m/%d/%Y")
You would not necessarily chain it together in this way in your code—Brendan Benson's response provides a good approach, for example—although you might not need something fancy if you're only doing this in one place.

Related

Is there a gem that provides support to detect changes to native ruby type instances?

Although I agree that extending native types and objects is a bad practice, inheriting from them should not be.
In a supposedly supporting gem (that I could not find), the way that the native types were to be used would be as follows:
require 'cool-unkown-light-gem'
class MyTypedArray < CoolArray # would love to directly < Array
def initialize(*args)
super(*args)
# some inits for DataArray
#caches_init = false
end
def name?(name)
init_caches unless !#caches_init
!!#cache_by_name[name]
end
def element(name)
init_caches unless !#caches_init
#cache_by_name[name]
end
private
# overrides the CoolArray method:
# CoolArray methods that modify self will call this method
def on_change
#caches_init = false
super
end
def init_caches
return #cache_by_name if #caches_init
#caches_init = true
#cache_by_name = self.map do |elem|
[elem.unique_name, elem]
end.to_h
end
end
Any method of the parent class not overridden by the child class that modifies self would call, let's say (in this case), the on_change function. Which would allow to do not have to re-define every single one of those methods to avoid losing track on changes.
Let's say the MyTypedArray would array Foo objects:
class Foo
attr_reader :unique_name
def initialize(name)
#unique_name = name
end
end
a short example of the expected behaviour of its usage:
my_array = MyTypedArray.new
my_array.push( Foo.new("bar") ).push( Foo.new("baz") )
my_array.element("bar").unique_name
# => "bar"
my_array.shift # a method that removes the first element from self
my_array.element("bar").unique_name
# => undefined method `unique_name' for nil:NilClass (NoMethodError)
my_array.name?("bar")
# => false
I understand that we should search for immutable classes, yet those native types support changes on the same object and we want a proper way to do an inheritance that is as brief and easy as possible.
Any thoughts, approaches, or recommendations are more than welcome, of course. I do not think I am the only one that have thought on this.
The reason why I am searching for a maintained gem is because different ruby versions may offer different supported methods or options for native types / classes.
[Edit]
The aim of the above is to figure out a pattern that works. I could just follow the rules and suggestions of other posts, yet would not get things work the way I am intended and when I see it proper (a coding language is made by and for humans, and not humans made for coding languages). I know everyone is proud of their achievements in learning, developing and making things shaped in a pattern that is well known in the community.
The target of the above is because all the methods of Array are more than welcome. I do not care if in the version 20 of Ruby they remove some methods of Array. By then my application will be obsolete or someone will achieve the same result in far less code.
Why Array?
Because the order matters.
Why an internal Hash?
Because for the usage I want to make of it, in overall, the cost of building the hash compensates the optimization it offers.
Why not just include Enumerable?
Because we just reduce the number of methods that change the object, but we do not actually have a pattern that allows to change #caches_init to false, so the Hash is rebuilt on next usage (so same problem as with Array)
Why not just whitelist and include target Array methods?
Because that does not get me where I want to be. What if I want anyone to still use pop, or shift but I do not want to redefine them, or even having to bother to manage my mixins and constantly having to use responds_to?? (perhaps that exercise is good to improve your skills in coding and read code from other people, but that is not what it should be)
Where I want to be?
I want to be in a position that I can re-use / inherit any, I repeat, any class (no matter if it is native or not). That is basic for an OOP language. And if we are not talking about an OOP language (but just some sugar at the top of it to make it appear as OOP), then let's keep ourselves open to analyse patterns that should work well (no matter if they are odd - for me is more odd that there are no intermediate levels; which is symptom of many conventional patterns, which in turn is symptom of poor support for certain features that are more widely required than what is accepted).
Why should a gem offer the above?
Well, let's humble it. The above is a very simple case (and even though not covered). You may gain in flexibility at some point by using what some people want to call the Ruby way. But at a cost when you move to bigger architectures. What if I want to create intermediate classes to inherit from? Enriched native classes that boost simple code, yet keeping it aligned with the language. It is easier to say this is not the Ruby way than trying to make the language closer to something that escalates well from the bottom.
I am not surprised that Rails and Ruby are almost "indistinctly" used by many. Because at some point, without some Rails support, what you have with Ruby is a lot of trouble. As, consequently, I am not surprised that Rails is so maintained.
Why should I redefine a pop, or a last, or first methods? For what? They are already implemented.
Why should I whitelist methods and create mixins? is that a object or method oriented programming?
Anyway... I do not expect anyone to share my view on this. I do see other patterns, and I will keep allowing my mind to find them. If anyone is open enough, please, feel free to share. Someone may criticize the approach and be right, but if you got there is because it worked.
To answer your question as it is written, no, there is no gem for this. This is not a possibility of the language, either in pure Ruby or in C which is used internally.
There is no mechanism in detect when self is changed, nor any way to detect if a method is pure (does not change self) or impure (does change self). It seems you want a way to "automatically" be able to know when a method is one or the other, and that, to put simply, is just not possible, nor is it in any language that I am aware of.
Internally (using your example) an Array is backed by a RArray structure in C. A struct is simple storage space: a way to look at an arbitrary block of memory. C does not care how you choose to look at memory, I could just as easily cast the pointer of this struct and say it is a now a pointer to an array of integers and change it that way, it will happily manipulate the memory as I tell it to, and there is nothing that can detect that I did so. Now add in the fact that anyone, any script, or any gem can do this and you have no control over it, and it just shows that this solution is fundamentally and objectively flawed.
This is why most (all?) languages that need to be notified when an object is changed use an observer pattern. You create a function that "notifies" when something changes, and you invoke that function manually when needed. If someone decides to subclass your class, they need only continue the pattern to raise that function if it changes the object state.
There is no such thing as an automatic way of doing this. As already explained, this is an "opt-in" or "whitelist" solution. If you want to subclass an existing object instead of using your own from scratch, then you need to modify its behavior accordingly.
That said, adding the functionality is not as daunting as you may think if you use some clever aliasing and meta-programming with module_eval, class_eval or the like.
# This is 100% untested and not even checked for syntax, just rough idea
def on_changed
# Do whatever you need here when object is changed
end
# Unpure methods like []=, <<, push, map!, etc, etc
unpure_methods.each do |name|
class_eval <<-EOS
alias #{name}_orig #{name}
def #{name}(*args, &block)
#{name}_orig(*args, &block)
on_changed
end
EOS
end

Replace class and variables names in code snippet

I would like to insert some gist-s of my code in CV. In order not to give idea what this code is about I want to replace all classes, methods and variables names with some random strings automatically (using some script or online creator?), so that I can show "how I write" but I don't show real functionality.
class User
def initialize(email)
#email = email
#is_admin = false
end
def give_admin
self.update(is_admin: true)
end
[...]
end
I would like to change into:
class Class1
def method_1(var1)
#var1 = var1
#var2 = false
end
def method_2
self.update(var2: true)
end
[...]
end
or maybe someone know better way to show somebody else "how does my code looks like but without showing him functionality"?
Thanks in advance
To answer your question:
You might want to use a Ruby source code uglifier/minifier (for example: ruby2ruby).
BUT (and that's all caps "but")
Don't do it! When someone is looking at your code, s/he does not want to see some random ruby code. The name of the class, the method names, etc. are very important in evaluating code. Who cares about the class names you have written in the past? Most probably, there are gazillion of other developers that have named their classes using exactly the same names as your showcase classes. So, post probably no one would care. Just give the exact classes you wrote, remove some private things that they may contain and share them.
If you really don't want to share some classes that you are really proud of, then write another (new) classes and showcase all your skills in there!
PS. If someone wants to evaluate your code without knowing the class and method names, then grab your code and run like hell! You probably better off without them! :) You will not learn much from that team lead. Or, if you do, you will learn the wrong things.

Any reason I should not be using send like this?

I am trying to keep my classes encapsulated as much as possible. Any reason that I should not use the send method like this?
class MyClass
def self.join_two_strings(first, second)
new.send(:join_two_strings, first, second)
end
def join_two_strings(first, second)
first + second
end
private :join_two_strings
end
Since #join_two_strings doesn't actually need any instance state, it should just be a class method.
class MyClass
def self.join_two_strings(first, second)
first + second
end
end
Yes, there is reason not to do that. It is because it is verbose. To achieve what you want, you should code like in Chris Heald's answer. (Chris Heald suggests what you should do, but does not answer your question).
To call the problem with your use of #send even more precisely, it is not verbosity, but obscuring of the design intent. Sometimes verbosity (such as using full words, rather than abbreviations) serves to reveal the design intent and shorten the time reader needs to understand your code. With your code example, the reader does not believe that what you want to achieve is mere joining of 2 strings, they keep searching for deeper meaning, before conceding that it is just a complicated method to do a simple thing (and possibly refactoring your code as Chris did). As for #send itself, do not fear it, do not fear to use it. Though #send should not be used as a tool to arbitrarily disrespect privacy of methods, on the other hand, Ruby methods are messages and you don't have to worry to be explicit about it, where there is a reason for it.

Is a bad practice to monkey patch a base ruby class?

I'm working on a ruby project in which we are planning to do some operations with ruby strings. Some operations are simple (like counting the number of words) and others more complex (like checking if a given string is in the correct language).
A possible way to implement this is by patching the String class with extra methods, without modifying any existing methods, and adding behaviors like "some string".word_count and "some string".cjk?.
Another approach, based on FileUtils is to create a class or module full of methods and always use string as parameters, like OddClassName.word_count("some string") and OddClassName.cjk?("some string"). We like the first better because of readability.
I understand that monkey patching a basic class as described in the first alternative can have name clashes. However, if this is the main application, not a library, should I worry with it at all?
So, the questions are:
Is adding methods to ruby base classes a bad practice? If yes, is that in all cases or only in some cases?
What is the best approach to accomplish this?
What could be the name of 'OddClassName'?
Please suggest any alternatives.
Monkey patching isn't considered to be a bad practice unless you are writing odd methods that do not have PatchedClass-related behavior (for example, String.monkeyPatchForMakingJpegFromString is rather bad, but Jpeg.fromString is good enough.)
But if your project is rather large, the libraries that you use in it may happen to have colliding patches, so you may have one more problem with all these patching stuffs. In Ruby 2.0, refinements come to an aid. They work as follows: you define a module, refine your (even core) class in it, and then use that module where it's necessary. So, in your code it works as:
YourClass.new.refinedMethodFromCoreClass #=> some result
But
CoreClass.refinedMethodFromCoreClass
produces undefined method exception.
That's all monkey patching stuff: monkey patching is useful and convenient, but refinements add some features, that make your code more secure, maintainable and neat.
I'd use a new class, call it Doc or something because getting the word count and checking languages sounds like operations for documents.
Let it take a string as a constructor parameter and have modifications chain to return a new Doc. Also give it a to_s method that returns the string.
class Doc
def initialize(str)
#str = str
end
def to_s
#str
end
define word_count, cjk?, etc.
end
Doc.new("Some document").word_count
# => 2

Best way of emulating enum in Ruby? (part two)

I'm new to Ruby so forgive me if this is something obvious..
I've made a class like so
class Element
attr_accessor :type
:type_integer
:type_string
end
(this is really just an example, not actual code)
Well, I've read Enums in Ruby and I'd prefer to go the Symbols route of having something like enumerations in other languages. I have a problem though, how can I keep my global scope clear while implementing this. What I'm wanting to be able to do is something like
e=Element.new
e.type=Element.type_integer
or something pretty simple and straight forward like that.
Symbols don't do anything to the global (or any other) scope (i.e. no variables or constants or anything else gets defined when you use symbols), so I guess the answer is: just use symbols and the global scope will be kept clear.
If you want to use e.type=Element.type_integer, while still using symbols, you could do:
class Element
def self.type_integer
:type_integer
end
end
Although I fail to see the upside vs. just using e.type = :type_integer directly.

Resources