Is there a style standard for Ruby hashes? [closed] - ruby-on-rails

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am not sure if I can ask about programming conventions on stackoverflow, but since my goal is to be better at programming coding and stylistically, I guess it cannot hurt.
I would like to know what is the best style to write a hash in ruby
I have seen
a = {a: 'a', b: 'b'}
b = { a: 'a', b: 'b' }
c = {:a=>'a', :b=>'b'}
d = {:a => 'a', :b => 'b'}
e = { :a => 'a', :b => 'b' }
I prefer the first because it matches arrays [a, b, c] or param('a', 'b')
but I have seen tutorials using the second style.
I know there might be personal preference but I want to know the convention like 'tabs should be two spaces instead of four'.
I know the hash rocket is older syntax, lets assume I'm using the newest rails and ruby verions.

From the Ruby Style Guide
# good - space after { and before }
{ one: 1, two: 2 }
# good - no space after { and before }
{one: 1, two: 2}
I personally favor
a = {a: 'a', b: 'b'}
The => are part of the old <= 1.8 hash syntax
Note, when using hashes in method calls, you can omit the {}
some_method a: 'a', b: 'b'

This is totally an opinion question, but my opinion answer is "B" above... It's easiest to read and is the newest "standard" for hashes. That said, there's nothing wrong with "A", but I think the extra spaces makes it easier to read.
Full disclosure, I still prefer "E" - I've never gotten away from hashrockets... But I'm old school like that.

Related

How to convert ruby hash_sym from hash arrow to hash colon [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 days ago.
Improve this question
In Rails: I like to convert
my_arrow_hash = {:a=>1,:b=>2,:c=>3}
to
My_colon_hash = {a: 1, b: 2, c: 3}
The two are identical. They both declare a hash with keys that are ruby symbols :a, :b, and :c.
The first declaration ({:a=>1,:b=>2,:c=>3}) uses the traditional ruby syntax to declare the hash.
The second declaration ({a: 1, b: 2, c: 3}) uses a newer and shorter syntax that was introduced in Ruby 1.9 and can only be used when the keys are ruby symbols.

What does "&:name" mean in Ruby [duplicate]

This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 8 years ago.
I saw it in some sample Ruby code someone had posted. It was something like:
a.sort_by(&:name)
where a is an array or ActiveRecord objects and :name is one of the attributes.
I have never seen &:name and Ruby's Symbol class documentation says nothing about it. Probably something really simple. :)
Unary Ampersand is address of a function/block/lambda
In this case, it means that the .sort_by function will use each a's element's function named name for comparison
Mostly it used for something else, like this:
[1,2,3].map{ |x| x.to_s } # ['1','2','3']
That could be shortened as:
[1,2,3].map(&:to_s)
So, in your case, a.sort_by(&:name) is a shorthand to:
a.sort_by{ |x| x.name }

Regex that gets only initials [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is there a way to create a regex for initials without using back references? For example, say I want initials for
New.York
And the regex to output
N.Y. (or n.y)
So far I have the following:
.\.[a-zA-Z]+
This outputs the last the initial of the first word instead of the first initial: w.y.
UPDATE**
I'm also assigned the RegExp to variable and using the =~ to test some things.
You could remove all the lowercase letters using gsub function,
irb(main):004:0> str = "New.York"
=> "New.York"
irb(main):006:0> str.gsub(/[a-z]+/, "")
=> "N.Y"
A ruby way to do this given your input of "New.York" could be:
str.split('.').collect { |s| s[0] }.join('.')
which would return 'N.Y'
Use this regex and you should only output the groups \1 and \2.
([a-zA-Z])[^.]*\.([a-zA-Z]).*?\b
DEMO
If you want to do a replacement you should use \1.\2
You could use the capital letters to dictate the regex match using something like this:
[15] pry(main)> str
=> "New.York"
[16] pry(main)> str.scan(/[A-Z]+/).join('.')
=> "N.Y"

How to sort .edu email domains? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I am using Ruby on Rails to make a university-exclusive website that categorizes all registered users into their specific universities via their ".edu" email. Nearly all US-based universities have an "xyz.edu" email domain. In essence, everyone that signs up with their ".edu" email would all be categorized with a similar "domain.edu".
I've searched for a regex to look for like-domains.edu and assign them into a variable or specific indexes, but I must be looking in the wrong place because I cannot find how to do this.
Would I use regex for this? Or maybe a method after their email has been verified?
I would appreciate any help or feedback I can get.
You could use a regex to extract domain names:
"gates#harvard.edu" =~ /.*#(.*)$/
This simple regexp will capture everything after the # symbol. You can experiment more with this regexp here.
However, what you have to think about is how to handle cases like gates#harvard.edu vs gates#seas.harvard.edu.
My example will parse them out as different entities: harvard.edu vs seas.harvard.edu.
I would probably go ahead and create an institution/university/group model that would hold those users. It would be easier now than later down the line. But, in an effort to answer your question, you could do something like:
array_of_emails = ['d#xyz.edu', 'a#abc.edu', 'c#xyz.edu', 'b#abc.edu' ]
array_of_emails.sort_by! { |email| "#{email[email.index('#')..-1]}#{email[0..email.index('#')]}" }
EDIT: Changed sort! to sort_by!
Dealing with domains is going to get a lot more complex in the future, with new TLDs coming on line. Assuming that .edu is the only educational TLD will be wrong.
A simple way to grab just the domain for now is:
"gates#harvard.edu"[/(#.+)$/, 1] # => "#harvard.edu"
That will handle things like:
"gates#mail.harvard.edu"[/(#.+)$/, 1] # => "#mail.harvard.edu"
If you don't want the #, simply shift the opening parenthesis right one character:
pattern = /#(.+)$/
"gates#harvard.edu"[pattern, 1] # => "harvard.edu"
"gates#mail.harvard.edu"[pattern, 1] # => "mail.harvard.edu"
If you want to normalize the domain to strip off sub-domains, you can do something like:
pattern = /(\w+\.\w+)$/
"harvard.edu"[pattern, 1] # => "harvard.edu"
"mail.harvard.edu"[pattern, 1] # => "harvard.edu"
which only grabs the last two "words" that are separated by a single ..
That's somewhat naive, as non-US domains can have a country code, so if you need to handle those you can do something like:
pattern = /(\w+\.edu(?:\.\w+)?)$/
"harvard.edu"[pattern, 1] # => "harvard.edu"
"harvard.edu.cc"[pattern, 1] # => "harvard.edu.cc"
"mail.harvard.edu.cc"[pattern, 1] # => "harvard.edu.cc"
And, as to whether you should do this before or after you've verified their address? Do it AFTER. Why waste your CPU time and disk space processing invalid addresses?
array_of_emails = ['d#xyz.edu', 'a#abc.edu', 'c#xyz.edu', 'b#abc.edu' ]
x = array_of_emails.sort_by do | a | a.match(/#.*/)[0] end
x.each do |a|
puts a
end

What is the difference between colon placement in :something and somethingelse: [duplicate]

This question already has answers here:
Is there any difference between the `:key => "value"` and `key: "value"` hash notations?
(5 answers)
Closed 7 years ago.
I am struggling to understand difference between :symbol and text: with regards to the colon placement. My understanding is that when we use :symbol we are referring to this object and whatever it contains, where as text: is used to assign a value to the text like we would a variable. Is this correct or could someone elaborate on the usage. Thank you.
:whatever is a symbol, you've got that part right.
When you're using a hash, this was how you used to define it in 1.8x ruby:
{:key => value, :another_key => another_value}
This is known as the hashrocket syntax. In ruby 1.9x, this changed to:
{key: value, another_key: another_value}
There is backward compatibility that will still load the hashrocket syntax... But, in 1.9, 'key:' is a symbol
the {:key => value} is the old hash syntax in ruby, now we have a new hash syntax that is more like json so
{:key => value}
is the same as
{key: value}
The old one, we’re all familiar with is:
old_hash = {:simon => "Talek", :lorem => "Ipsum"}
This is all nice and dandy, but it could be simpler and cleaner. Check out the Ruby 1.9 style, it sort of resembles JSON:
new_hash = {simon: "Talek", lorem: "Ipsum"}
But now you look closer and ask, “But previously the key was a symbol explicitly, what’s with this now?”.
Well you’re right, the new notation is sort of a syntactic sugar for the most common style of hashes out there, the so called symbol to object hash. If you do this in the irb, you’ll see ruby returning the old school hash, with the symbols used as keys:
> new_hash = {simon: "Talek", lorem: "Ipsum"}
=> {:simon=>"Talek", :lorem=>"Ipsum"}
If you need to have arbitrary objects as your hash keys, you’ll still have to do it old school.
ref:http://breakthebit.org/post/8453341914/ruby-1-9-and-the-new-hash-syntax

Resources