model Sample has attributes car,bike
x ="bike"
y = Sample.new
How can I do?
y.x ??
It gives me an error
Is there any way I can do it, I know that x is an attribute but I dont know which one.
So how can I get y.x?
You can use send to invoke a method on an object when the method is stored as a string:
x = "bike"
y = Sample.new
y.send(x) # Equivalent to y.bike
The following are equivalent, except that you may send protected methods:
object.method_name
object.send("method_name")
object.send(:method_name)
You have to use dynamic message passing. Try this:
y.send :bike
Or, in your case
y.send x
Related
Hello I have the following object
object = [#<ShopifyAPI::DiscountCode:0x000000000e1c78a8 #attributes={"code"=>"Disc2", "amount"=>"1.00", "type"=>"percentage"}, #prefix_options={}, #persisted=true>]
How can I properly access the "code" name of that object?
I have tried object[:code] and object.code but it appears I am overlooking something.
object is an array of ShopifyAPI::DiscountCode.
The best way to access it is
object[0].attributes['code']
If u want code of all the objects available in the array, you could get the array of values by
object.map { |obj| obj.attributes['code'] }
Given that this is an Array of ShopifyAPI::DiscountCodes (which inherit from ActiveResource::Base)
You can call the code method on them. eg:
object[0].code
#=> "Disc2"
object.map(&:code)
#=> ["Disc2"]
First, object is array:
obj0 = object[0]
Second, this is instance variable:
attributes = obj0.instance_variable_get(:#attributes)
Last, gets values by keys:
attributes['code']
I am new to Ruby, so let me describe the context of my problem first:
I have a json as input which has the following key / value pair:
{
"service": "update"
}
The value has many different values for example: insert,delete etc.
Next there is a method x which handles the different requests:
def x(input)
case input[:service]
services = GenericService.new
when "update"
result = services.service(UpdateService.new,input)
when "insert"
result = services.service(InsertService.new,input)
when "delete"
result = services.service(DeleteService.new,input)
....
....
else
raise "Unknown service"
end
puts JSON.pretty_generate(result)
end
What is bothering me is that I still need to use a switch statement to check the String values (reminds me of 'instance of' ugh..). Is there a cleaner way (not need to use a switch)?
Finally I tried to search for an answer to my question and did not succeed, if however I missed it feel free to comment the related question.
Update: I was thinking to maybe cast the string to the related class name as follows: How do I create a class instance from a string name in ruby? and then call result = services.services(x.constantize.new,input) , then the class names ofcourse needs to match the input of the json.
You can try something like:
def x(input)
service_class_name = "#{input[:service].capitalize}Service"
service_class = Kernel.const_get(service_class_name)
service_class.new(input).process
end
In addition you might want to check if this is a valid Service class name at all.
I don't understand why you want to pass the service to GenericService this seems strange. let the service do it's job.
If you're trying to instatiate a class by it's name you're actually speaking about Reflection rather than Polymorphism.
In Ruby you can achieve this in this way:
byName = Object.const_get('YourClassName')
or if you are in a Rails app
byName= 'YourClassName'.constantize
Hope this helps
Just first thoughts, but you can do:
eval(services.service("#{input[:service].capitalize}Service.new, #{input})") if valid_service? input[:service]
def valid_service?
w%(delete update insert).include? input[:service]
end
As folks will no doubt shout, eval needs to be used with alot of care
I have tried finding this in the docs but don't quite get it. I am starting to work with Classes, When I try to get the result, I get instead of the actual 'width' I maybe I need to get but not sure.. It sounds too complicated just to get a result. Can someone advise?
I have:
class Rectangle(object):
def __init__(self, pt_ll, pt_ur):
self.ll = pt_ll
self.lr = Point(pt_ur.x, pt_ll.y)
self.ur = pt_ur
self.ul = Point(pt_ll.x, pt_ur.y)
def width(self):
"""Returns the width-float of the Rectangle."""
w = self.ur.x - self.ll.x
return w
Then I call it:
r = Rectangle(Point(0,0), Point(10,10))
print r.ur.x
print r.ll.x
print r.width
and get this output:
10.0
0.0
<bound method Rectangle.width of <__main__.Rectangle object at 0x000000000B5CBC50>>
print r.width
This returns the width method itself, this is what you see in the output.
You want to call that method so you need to instead do this:
print r.width()
This hints at an interesting thing about python, you can pass around functions just like you can with other variables.
I'm using Ruby 1.9.2 and need to go through all of the values for a table to make sure everything is in UTF-8 encoding. There are a lot of columns so I was hoping to be able to use the column_names method to loop through them all and encode the values to UTF-8. I thought this might work:
def self.make_utf
for listing in Listing.all
for column in Listing.column_names
column_value_utf = listing.send(column.to_sym).encode('UTF-8')
listing.send(column.to_sym) = column_value_utf
end
listing.save
end
return "Updated columns to UTF-8"
end
But it returns an error:
syntax error, unexpected '=', expecting keyword_end
listing.send(column.to_sym) = column_value_utf
I can't figure out how to make this work correctly.
You're using send wrong and you're sending the wrong symbol for what you want to do:
listing.send(column + '=', column_value_utf)
You're trying to call the x= method (for some x) with column_value_utf as an argument, that's what o.x = column_value_utf would normally do. So you need to build the right method name (just a string will do) and then send the arguments for that method in as arguments to send.
I have a two mailers
welcome_manger(user) welcome_participant(user)
Both send different information and have different layouts.
when I call the deliver method I would like to use something like the following
UserMailer.welcome_self.role(self.user)
This does not work. How can I accomplish this?
Something like this perhaps:
m = 'welcome_' + self.role
UserMailer.send(m.to_sym, [self.user])
Assuming that self.role returns a String.
The send method invokes a method by name:
obj.send(symbol [, args...]) → obj
Invokes the method identified by symbol, passing it any arguments specified.
So you just need to build the appropriate method name as a string and then convert it a symbol with to_sym.