Use getproperty, setproperty and hasproperty instead of $ - grails

I have something like this.
def temp = "field"
object."$temp" = "hi"
This works fine.
But can i use setproperty, getproperty and hasproperty somehow to implement the same.
Thanks

You can replace object."$temp" = "hi" with object.setProperty(temp, "hi"), and object."$temp" with object.getProperty(temp). There is also the square bracket syntax:
e = new Expando()
def field = 'name'
e[field] = 'john doe' // set
assert e[field] == 'john doe' // get
e.setProperty(field, 'foo') // set
assert e.getProperty(field) == 'foo' // get
if (!e.hasProperty('bar')) { // has property
e['bar'] = 'my bar'
}
assert e.getProperty('bar') == 'my bar'

Related

Minitest controller sequence to assert changes to calculated variable

First test
assert_changes '#user_end.login_name' do
post update_login_user_path(id: #user_end.id), params: { user: { email: '', mobile_nation_id: 1, mobile: 876321 } }
end
"#user_end.login_name" didn't change.
Expected "end_consumer_email#mail.co" to not be equal to "end_consumer_email#mail.co".
Second test
post update_login_user_path(id: #user_end.id), params: { user: { email: '', mobile_nation_id: 1, mobile: 876321 } }
assert_equal(39876321, #user_end.login_name)
Expected: 39876321
Actual: "end_consumer_email#mail.co"
Both are returning the fixture value and not the expected value, which is generated in practice in the application. The controller action :
if params[:user][:email].present? || params[:user][:mobile].present?
set_user_login_name
end
calls a method
def set_user_login_name
if !params[:user][:email].blank?
params[:user][:login_name] = params[:user][:email].gsub(/\s+/, "")
elsif !params[:user][:mobile_nation_id].blank? && !params[:user][:mobile].blank?
#nation = Nation.where(id: params[:user][:mobile_nation_id]).first
params[:user][:login_name] = #nation.phone_cc.to_s + params[:user][:mobile].to_s
params[:user][:twilio_number] = '+' + #nation.phone_cc.to_s + params[:user][:mobile].to_s
else
params[:user][:login_name] = ''
end
params[:user][:kee] = SecureRandom.alphanumeric(32)
params[:user][:virtual_qr_code] = params[:user][:login_name] + params[:user][:kee]
end
As the methods work in practice, it is clear I do not grasp how to properly use these two assertions. I don not seem to be able to call the updated record (whereas for a create assert_equal('18831912200', User.last.login_name) is straightforward)
How can either one of them be cast to assert the above method?

Remove characters after any tags

I am working in rails. I have one doubt.
1. a = "ABCD123"
I want to print ABCD123
2. b = "ABCDE<123>"
I want to print ABCDE
For that I am using this
a.scan(/\b[A-Za-z]+\b/).join and
b.scan(/\b[A-Za-z]+\b/).join.
First one is giving nil but I want to print it as ABCD123 and second one is showing correct what I want.
Could anyone please help me. Thanks.
code below can remove all tags in the string
a = "ABCD123"
b = "ABCDE<123>"
a.gsub /<.*?>/, '' # => "ABCD123"
b.gsub /<.*?>/, '' # => "ABCDE"
def conversion(str)
index_number = str.index(/[\W_]+/)
if index_number.present?
main_str = str.gsub(str[index_number..],'')
else
main_str = str
end
return main_str
end
or you can use
b = "ABCD-123"
b.match(/(^[A-Za-z0-9]+)/)[1]
#=> "ABCD"
You can try following,
b = "ABCDE<123>"
b[/[^<>]+/]
# => "ABCDE"
Since comments are a bit limited:
Here is a small snippet to test different inputs.
strings = %w[ABCD123 ABCD<123> ABCD <123>ABCDE]
strings.each do |string|
match = string.match(/(^[A-Za-z0-9]+)/)
if match
puts "'#{string}' => #{match[1]}"
else
puts "'#{string}' does not match pattern"
end
end
Is this the desired behaviour?
'ABCD123' => ABCD123
'ABCD<123>' => ABCD
'ABCD' => ABCD
'<123>ABCDE' does not match pattern

How to add property to ruby variable?

I want to create variable item
And write something like this:
item.property1 = "whatever"
item.poperty2 = "whatever"
How do I do this?
Right now I am doing it like this:
item = {}
item [:property1] = "whatever"
Any other options?
Here are the simplest solutions I know of:
If you know the attributes in advance, then use a Struct:
Item = Struct.new(:property1, :property2)
item = Item.new('blue', 'medium') # or:
item = Item.new
item.property1 = 'blue'
item.property2 = 'medium'
puts item.property1
puts item.property2
Otherwise, you can use an OpenStruct:
require 'ostruct'
item = OpenStruct.new
item.property1 = 'blue'
item.property2 = 'medium'
puts item.property1
puts item.property2
You need to create an object to access variables like that.
class Item
attr_accessor :property1, :property2
end
Then you could do what you wrote:
item = Item.new
item.property1 = "whatever"
item.poperty2 = "whatever"
If you are talking about a Rails database object there is more to it though (like writing a database migration first).

Create dynamically closures in Groovy from a String object

i would like to create a query with the Criteria API in Grails (GORM).
The query will have to be something like this:
MyEntity.createCriteria().list{
assoc{
parent{
eq("code", val)
}
}
}
What i need is to build the nested closure dynamically from a String object. The String for the example above will be "assoc.parent.code" . I splitted the String by dot (by doing String.split("\\.") ) but i don't know how to construct the nested closures:
assoc{
parent{
eq("code", val)
}
}
dynamically based on the array of the splitted Strings above.
What about createAlias?. You could try something like this:
def path = "assoc.parent.code"
def split = path.split(/\./)
MyEntity.createCriteria().list {
// this will get you 'createAlias( assoc.parent, alias1 )'
createAlias split.take( split.size() - 1 ), "alias1"
// this will get you 'eq(alias1.code, userInput)'
eq "alias1.${split[-1]}", userInput
}
This snippet is not generic, but you get the idea.
Update
Not conventional, but you can build a string containing the code with the closures and evaluate it using GroovyShell:
assoc = 'assoc.parent.child.name'
split = assoc.split( /\./ )
path = split[-2..0] // will get us 'child.parent.assoc';
// we will build it from inside-out
def firstClosure = "{ eq '${split[-1]}', 'john doe' }"
def lastClosure = firstClosure
for (entity in path) {
def criteriaClosure = "{ ${entity} ${lastClosure} }"
lastClosure = criteriaClosure
}
assert lastClosure == "{ assoc { parent { child { eq 'name', 'john doe' } } } }"
def builtClosure = new GroovyShell().evaluate("return " + lastClosure)
assert builtClosure instanceof Closure
A more generic approach would be to metaClass String as below, and use it for any kind of separator
. | , - ~ and more.
String.metaClass.convertToClosureWithValue = {op, val ->
split = delegate.split(op) as List
if(split.size() == 1) {return "Cannot split string '$delegate' on '$op'"}
items = []
split.each{
if(it == split.last()){
items << "{ eq '$it', $val }"
split.indexOf(it).times{items.push("}")}
} else {
items << "{$it"
}
}
println items.join()
new GroovyShell().evaluate("return " + items.join())
}
assert "assoc.parent.child.name".convertToClosureWithValue(/\./, "John Doe") instanceof Closure
assert "assoc-parent-child-name".convertToClosureWithValue(/\-/, "Billy Bob") instanceof Closure
assert "assoc|parent|child|grandChild|name".convertToClosureWithValue(/\|/, "Max Payne") instanceof Closure
assert "assoc~parent~child~grandChild~name".convertToClosureWithValue('\\~', "Private Ryan") instanceof Closure
assert "assocparentchildname".convertToClosureWithValue(/\|/, "Captain Miller") == "Cannot split string 'assocparentchildname' on '\\|'"
//Print lines from items.join()
{assoc{parent{child{ eq 'name', John Doe }}}}
{assoc{parent{child{ eq 'name', Billy Bob }}}}
{assoc{parent{child{grandChild{ eq 'name', Max Payne }}}}}
{assoc{parent{child{grandChild{ eq 'name', Private Ryan }}}}}

How to set a variable to another instance by reference

given the following code:
vars = instance_variables.map(&method(:instance_variable_get))
vars.each {|v| v = 123}
would that set #something = 123?
taking it a step further
is it the same if i have
vars = instance_variables.map(&method(:instance_variable_get))
vars.each {|v| doSomething(v) }
def doSomething(var)
var = 123
end
how would i mutate var from inside a function?
You can test this in irb pretty quickly:
#something = 456
instance_variables
# => [:#something]
instance_variables.map(&method(:instance_variable_get)).each { |v| v = 123 }
#something
# => 456 (i.e. "didn't mutate #something")
def doSomething(var)
var = 123
end
vars = instance_variables.map(&method(:instance_variable_get))
vars.each { |v| doSomething(v) }
#something
# => 456 (i.e. "didn't mutate #something")
Object#instance_variable_set, however, does change the value of #something:
#something = 456
instance_variables.each { |v| instance_variable_set(v, 123) }
#something
# => 123
Agreeing with pje, you probably should have tested this in irb, but I'm assuming you want to capture a setter for every instance variable, so I'd recommend something like:
setters = instance_variables.map{|v| lambda { |val| instance_variable_set(v, val) }}
then you can just do setters[0].call(__VALUE__) and it will set the value accordingly.
What is it you are trying to achieve?

Resources