Different result for Regexp match with Rails and Rubular? - ruby-on-rails

I am using Rails 4.0.0 with Ruby 2.0.0 p247. I am writing an URL regexp matcher but I have no idea why it does not work:
2.0.0-p247 :033 > REGEXP = %r{\Ahttps:\/\/#{ Rails.configuration.aws[:bucket] }\.s3(-#{Rails.configuration.aws[:region]}|)\.amazonaws\.com\/(?<path>uploads\/.+\/(?<filename>.+))\?.+\z}.freeze
=> /\Ahttps:\/\/test-gem\.s3(-eu-west-1|)\.amazonaws\.com\/(?<path>uploads\/.+\/(?<filename>.+))\?.+\z/
2.0.0-p247 :034 > url = "https://test-gem.s3.amazonaws.com/uploads/2alrg16mvx6r-29590d114fb3257846c1a03330418da9/3031674-poster-p-1-for-25.jpg"
=> "https://test-gem.s3.amazonaws.com/uploads/2alrg16mvx6r-29590d114fb3257846c1a03330418da9/3031674-poster-p-1-for-25.jpg"
2.0.0-p247 :035 > REGEXP.match(url)
=> nil
But when I try to debug in things like Rubular, it does work. Any idea? Thanks!

Remove \?.+ in the end if your regexp

Might be a bug with Ruby 2.0.0. I'm using 2.1.3 and it works like you'd expect.
> r = /\Ahttps:\/\/test-gem\.s3(\A-eu-west-1\z|)\.amazonaws\.com\/(?<path>uploads\/.+\/(?<filename>.+))\z/
=> /\Ahttps:\/\/test-gem\.s3(\A-eu-west-1\z|)\.amazonaws\.com\/(?<path>uploads\/.+\/(?<filename>.+))\z/
> r.match("https://test-gem.s3.amazonaws.com/uploads/2alrg16mvx6r-29590d114fb3257846c1a03330418da9/3031674-poster-p-1-for-25.jpg")
=> #<MatchData
"https://test-gem.s3.amazonaws.com/uploads/2alrg16mvx6r-29590d114fb3257846c1a03330418da9/3031674-poster-p-1-for-25.jpg"
path:"uploads/2alrg16mvx6r-29590d114fb3257846c1a03330418da9/3031674-poster-p-1-for-25.jpg"
filename:"3031674-poster-p-1-for-25.jpg">

Related

simple_format changes the text itself

In Rails 3.0, the helper method simple_format changes the parameter itself.
I expected that it only returns the wrapped text.
2.0.0-p648 :001 > Rails.version
=> "3.0.20"
2.0.0-p648 :002 > s = "Hello"
=> "Hello"
2.0.0-p648 :003 > helper.simple_format(s)
=> "<p>Hello</p>"
2.0.0-p648 :004 > s
=> "<p>Hello</p>"
I checked with Rails 4.2 and it doesn't change the text.
Can someone please explain it?
Sam
The difference between implementations of this method in Rails 4.2 and Rails 3.0 is that in Rails 3.0 the passed string is modified (mutated by gsub!) and in Rails 4.2 it's not (it just returns a new modified string):
Rails 4.2:
2.4.0 :006 > s = "hello"
=> "hello"
2.4.0 :007 > simple_format s
=> "<p>hello</p>"
2.4.0 :008 > s
=> "hello"
The source code of different implementations can be found in the documentation

method match1.regex seems not working in ruby

I'm following a tutorial on regular expressions in ruby, but a method called regex that seems not working
Tutorial
re = /(\w*)\s(\w*),\s?([\w\s]*)/
match1 = str1.match re
match2 = str2.match re
match1.regex # => wsw,s[ws] (this is IRB's unique way of showing regular expressions; it will still work normally)
My console
The regex method the method throws an error
1.9.3-p547 :033 > re = /(\w*)\s(\w*),\s?([\w\s]*)/
=> /(\w*)\s(\w*),\s?([\w\s]*)/
1.9.3-p547 :034 > match1 = str1.match re
=> #<MatchData "Joe Schmo, Plumber" 1:"Joe" 2:"Schmo" 3:"Plumber">
1.9.3-p547 :035 > match2 = str2.match re
=> #<MatchData "Stephen Harper, Prime Minister" 1:"Stephen" 2:"Harper" 3:"Prime Minister">
1.9.3-p547 :036 > match1.regex
NoMethodError: undefined method `regex' for #<MatchData "Joe Schmo, Plumber" 1:"Joe" 2:"Schmo" 3:"Plumber">
from (irb):36
from /home/fernando/.rvm/rubies/ruby-1.9.3-p547/bin/irb:12:in `<main>'
1.9.3-p547 :037 >
I think it should be
match1.regexp
with a final 'p'

Rails n elements before last

In Rails I often do this:
Model.last(5).first
This retrieves element last-5.
Is there a built-in way of doing this?
The more common way is offset()
Model.offset(5).last
Edit (for lazy people):
1.8.7 :001 > User.first.id
=> 1
1.8.7 :002 > User.last.id
=> 143455
1.8.7 :003 > User.offset(5).last.id
=> 143450

Rails / Ruby not following Rublar on regular expression

I have the following expression that I have tested in Rubular and that successfully matches against a snippet of HTML:
Official Website<\/h3>\s*<p><a href="([^"]*)"
However, when I run the expression in Ruby, using the following code, it returns no matches. I've reduced it down to "Official\s*Website" and it matches that, but nothing further.
Are there any additional options I need to set, or anything else that I need to do to configure Ruby/Rails to start tracking Rubular?
matches = sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
if matches.nil?
puts "no matches"
else
puts "matches"
end
This is the relevant part of the snippet I'm matching against:
<h3>Official Website</h3><p>website.com</p>
your regular expression is correct. rubular should be working the same way your code does.
i tested it against ruby 1.8.7 and 1.9.3
irb(main):006:0> sidebar = ' <h3>Official Website</h3><p>website.com</p>'
=> " <h3>Official Website</h3><p>website.com</p>"
irb(main):007:0> sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
=> #<MatchData "Official Website</h3><p><a href=\"http://website.com\"" 1:"http://website.com">
-
1.9.3p0 :005 > sidebar = ' <h3>Official Website</h3><p>website.com</p>'
=> " <h3>Official Website</h3><p>website.com</p>"
1.9.3p0 :006 > sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
=> #<MatchData "Official Website</h3><p><a href=\"http://website.com\"" 1:"http://website.com">
if you want to quickly check why stuff is not working, you should try it in IRB or in your rails console. most of the times it's typo or bad encoding.

In Ruby on Rails, should we use content_for?(:foobar)?

This is for Rails 3, almost always I think a content_for?(:foo) is followed by content_for(:foo) (in haml):
%title= content_for?(:title_for_page) ? "#{content_for(:title_for_page)} - Our great website" : 'Our great website'
So instead of doing 2 lookups, isn't it better to just do 1 lookup and use longer code:
- title_for_page = content_for(:title_for_page) # is "" when not previously set
%title= title_for_page.blank? ? 'Our great website' : "#{title_for_page} - Our great website"
? But if content_for? is implemented as a hash, then maybe it is super quick anyway, comparable to the blank? anyways?
A one-liner to solve the problem:
- title_for_page = (c = content_for(:title_for_page)).blank? ? 'Our great website' : "#{c} - Our great website"
Only way to find out is to test :)
ruby-1.9.2-p136 :001 > h = {:mike => "test"}
=> {:mike=>"test"}
ruby-1.9.2-p136 :004 > Benchmark.ms do
ruby-1.9.2-p136 :005 > h[:mike].present?
ruby-1.9.2-p136 :006?> end
=> 0.029087066650390625
ruby-1.9.2-p136 :007 > Benchmark.ms do
ruby-1.9.2-p136 :008 > h[:mike].blank?
ruby-1.9.2-p136 :009?> end
=> 0.011205673217773438
I am using present?, as per the source of content_for?
Interesting that blank? is faster than present?, isn't it? Time to explore.
Lets look at the source code for present?:
Woah, it turns out present? just calls blank? and negates it.

Resources