Do you know any elegant way to achieve this in ruby plz ?
string = 'title,url'
#expected final variable => :title,:url or 'title','url'
I've looked in the API documentation (both ruby and rails) and didn't find any simple method, before writing any loop I wanted to be sure I wasn't missing something.
Thx !
Try this:
string.split(",").map &:to_sym # => [:title, :url]
Related
I'd love to use a method signature like:
def register(something, on:, for:)
This works, but I can't work out how to use "for" without causing a syntax error! Rather annoying, anyone know a way around this?
The problem is not the method definition line that you posted, the problem is the usage of the for variable inside the method body. Since for is a reserved word, you cannot use it as a plain variable name, but you can use it as part of a hash. In your case that means you must resort to using arbitrary keyword arguments (**opts), but you can use the keyword_argument for: in the method call. You may want to raise an ArgumentError if the key is not present to emulate the behavior of the method signature you posted above.
def register(something, on:, **opts)
raise ArgumentError, 'missing keyword: for' unless opts.has_key?(:for)
for_value = opts[:for]
puts "registering #{something} on #{on} for #{for_value}"
end
register 'chocolate chips', on: 'cookie'
# ArgumentError: missing keyword: for
register 'chocolate chips', on: 'cookie', for: 'cookie monster'
# registering chocolate chips on cookie for cookie monster
In Ruby, for is a reserved keyword - looks like you just cannot use them in other way to how they were meant to use.
That's the whole purpose of reserving keywords.
Additional resources on which keywords are reserved in Ruby:
http://www.rubymagic.org/posts/ruby-and-rails-reserved-words
http://www.java2s.com/Code/Ruby/Language-Basics/Rubysreservedwords.htm
(thanks #cremno for this comment) Both links don't mention ENCODING. Also, since 2.2.0 Ruby comes with an official document: $ ri ruby:keywords
UPD
Actualy, you can still use :for symbol as a key in hash (let's say, options hash), so, you can write like this:
def test(something, options = {})
puts something
puts options.values.join(' and ')
end
and it works like charm:
[4] pry(main)> test 'arguments', :for => :lulz, :with => :care, :while => 'you are writing code'
arguments
lulz and care and you are writing code
binding.local_variable_get(:for)
is a way I was thinking. Only works in ruby 2.1+ I think.
NOTE: Don't do this, I'm just interested in how you could get round it, you probably should just call your named parameter something else :)
I have spent already a long deal of time trying to figure out how to do this, I have also investigated but I have not found the right approach to it...?
basically I am trying to do something like the following:
types = ['type1','type2']
classes = ['class1','class2']
classes.each do |class|
types.each do |type|
template "/files/filename.txt" do
source "source_file.erb"
owner "root"
group "root"
mode "0440"
variables({
:pri_areas => node['area']['#{type}']['#{class}'],
:rev_areas => node['area']['#{type}']['#{class}']
})
end
end
end
Obviously I got all the attributes already defined so everything looks all right from that front..
I still cannot manage to get a loop with arrays like that withing the variables?
Maybe another different approach?
Any ideas/help?
Thanks very much.
Your code has some issues which you need to fix before it will properly work.
At first, class is a reserved keyword in Ruby and thus can't be used as a variable name. You should use another one, e.g. klass.
Secondly, class (or klass) as well as type are already strings inside your loop. Thus you don't need to attempt string interpolation. You can directly use this:
variables({
:pri_areas => node['area'][type][klass],
:rev_areas => node['area'][type][klass]
})
The reason why your string interpolation didn't work is that ruby knows two different kinds of String literals: ones with " and ones with '. The difference is that the ones delimited with ' do not allow string interpolation and generally do not interpret anything inside then as something else than the literal written string. Only in Strings delimited by ", you can perform string interpolation like "#{foo}" and use escape sequences like \n.
I am pretty new to ruby and sinatra but basically I have this route:
put '/user_list/:user_id' do
puts request.params["model"]
end
and it returns the following
{"password":"36494092d7d5682666ac04f62d624141","username":"nicholas","user_id":106,"firstname":"Nicholas","email":"nicholas#macpractice.com","is_admin":0,"lastname":"Rose","privileges":""}
I am now having a hard time accessing values of each of those. It doesn't really seem to be in hash format so I can't really do
request.params["model"][:password]
It just returns nil..
I just need to know what I can do to access those variables, or how to configure my request parameters to be in a good format to access variables.
Try request.params["model"]["password"]
A Hash's keys can consist of both symbols and strings. However, a string key is different than a symbol key.
Note the following:
h = {:name => 'Charles', "name" => 'Something else'}
h[:name] #=> 'Charles'
h["name"] #=> 'Something else'
EDIT:
In your particular situation, it appears request.params["model"] returns a string instead of a hash. There is a method String#[] which is a means of getting a substring.
s = "Winter is coming"
s["Winter"] #=> "Winter"
s["Summer"] #=> nil
This would explain your comments.
There are a couple things you can do to remedy your specific situation. I have found the most simplest way to be using JSON. (I'm sure there are others and maybe those will surface through other answers or through comments.)
require 'json'
hash_of_params = JSON.load(request.params["model"]).to_hash
hash_of_params["password"] #=> "36494092d7d5682666ac04f62d624141"
The standard Hash treats strings and symbols differently, and I'd be willing to bet that's what's happening in this case.
Use request.params["model"]["password"] to get the password.
The exception to that is when working with a HashWithIndifferentAccess which is part of ActiveSupport. For hashes of that type, either strings or symbols can be used to access the same elements.
Try the below,it will work too:
request.params["model"][:password.to_s]
I am working on a quoting mechanism in my app, where it should be possible to simply type #26, for example, in the comment form in order to quote comment 26 of that topic.
To check if a user wants to quote one or more comments in the first place, I put an if condition after my current_user.comments.build and before #comment.save.
But, just to make my question a bit more general and easier to adapt:
if #comment.content.include?(/\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i)
I want something like this. That example was for checking if the comment's content includes emails. But logically I get an "can't convert regexp to string" error.
How can you do the include? method in rails with an regexp? So, to check whether a text includes a string of a certain regex format?
Or is the controller the wrong place for such regex actions?
I do ruby regex'es this way:
stringObj.match(/regex/)
There's also
if #comment.content =~ /regex/
If you had an array of all previous comments #prev_comments and wanted to replace them all in one shot, you could:
pattern = /#(\d+)/
#comment.content.gsub(pattern) do
cur_match = Regexp.last_match
idx = cur_match[1].to_i - 1
#prev_comments[idx]
end
Trick is using Regexp.last_match to get the current match, which made me wonder if it was thread safe. It is, apparently.
adapted (stolen) from the below more general String extension
class String
def js_replace(pattern, &block)
gsub(pattern) do |_|
md = Regexp.last_match
args = [md.to_s, md.captures, md.begin(0), self].flatten
block.call(*args)
end
end
end
Source: http://vemod.net/string-js_replace
To match the nature of .include?
stringObj.match(/regex/).present?
Would give similar true/false outcomes if you're using Rails (or ActiveSupport)
I have the following code:
address = "#{(article/"div.address").inner_html.strip_html.squish}"
(using Hpricot)
And in some instances...
address = "#{(article/"div.address").inner_html.strip_html.squish}"
...is nil
I would like the script to keep chugging along, possibly replacing nil with an empty string.
Any tips?
Edit
I have traced the problem better to:
puts "#{link[0].to_s}\n" unless link.empty?
(.backtrace points to this particular line in the source.)
So the revised question is: why doesn't that line just not get parsed? Why does it throw an error? I thought that using unless will just skip it...
Use :to_s method:
nil.to_s == ''
Is try what you are looking for? http://api.rubyonrails.org/classes/Object.html#method-i-try
Thank you all for the support and helpful tips, in the end it was a matter of using the proper method, I ended up solving my problem by using:
unless uri.query.nil?
But I did come to make use of both .to_s and try in my source, and I wish I could pick two answers as the right one!