How to define method in class that can only be called from __init__ method
You need to preface do_something(self) with a double underscore. The code is below.
class Test:
def __init__(self):
self.__do_something # Should work
def __do_something(self):
# do something
test = Test()
test.__do_something()
How do I use define_method to create class methods?
I think in Ruby 1.9 you can do this:
class A
define_singleton_method :loudly do |message|
puts message.upcase
end
end
A.loudly "my message"
# >> MY MESSAGE
How to define method of class outside of class?
The lambda way
You example can be done with lambda
and =
:
class X:
pass
X.add = lambda s: s.a + s.b
The def way
The def
keyword won't allow you to assign directly to a class, but you can make a function, assign it, and then delete it. While this isn't what you were hoping for, it is likely the best you can do:
class X:
pass
def add(s):
return s.a + s.b
X.add = add
del add
How to define method of class outside of class?
The lambda way
You example can be done with lambda
and =
:
class X:
pass
X.add = lambda s: s.a + s.b
The def way
The def
keyword won't allow you to assign directly to a class, but you can make a function, assign it, and then delete it. While this isn't what you were hoping for, it is likely the best you can do:
class X:
pass
def add(s):
return s.a + s.b
X.add = add
del add
define_method in a class method
When you encounter seeming conundrums such as this one, try salting your code with puts self
statements:
module HashInitialized
puts "self when parsed=#{self}"
def hash_initialized(*fields)
puts "self within hash_initialized=#{self}"
define_method(:initialize) do |h|
missing = fields - h.keys
raise ArgumentError, "Not all fields set: #{missing}" if missing.any?
fields.each { |k| instance_variable_set("@#{k}", h[k]) }
end
private :initialize
end
end
#-> self when parsed=HashInitialized
class Cheese
extend HashInitialized
attr_accessor :color, :odor, :taste
hash_initialized :color, :odor, :taste
end
#-> self within hash_initialized=Cheese
As you see, self
is the class Cheese
, not Cheese
's singleton_class. Hence, the receiver for Module#define_method is Cheese
, so the method obligingly creates the instance method initialize
on Cheese
.
Cheese.instance_methods(false)
#=> [:color, :color=, :odor, :odor=, :taste, :taste=]
initialize
is not among the instance methods created on Cheese
because I modified the code slightly to make it a private method:
Cheese.private_instance_methods(false)
#=> [:initialize]
I also slightly altered the code that assigns values to the instance variables, and made the type of exception more specific.
If appropriate, you could change your argument test to:
raise ArgumentError, "Fields #{fields} and keys #{h.keys} don't match" if
(fields-h.keys).any? || (h.keys-fields).any?
You may wish to have initialize
create the assessors:
module HashInitialized
def hash_initialized(*fields)
define_method(:initialize) do |h|
missing = fields - h.keys
raise ArgumentError, "Not all fields set: #{missing}" if missing.any?
fields.each do |k|
instance_variable_set("@#{k}", h[k])
self.class.singleton_class.send(:attr_accessor, k)
end
end
private :initialize
end
end
class Cheese
extend HashInitialized
hash_initialized :color, :odor, :taste
end
Cheese.new :color=>'blue', odor: 'whew!', taste: "wow!"
=> #<Cheese:0x007f97fa07d2a0 @color="blue", @odor="whew!", @taste="wow!">
Define method in class dynamically
You can override the __setattr__()
method to dynamically update the _exec()
method depending on the value of attribute a
. Two different implementations for _exec()
are provided as methods in the class, and the appropriate one is selected whenever the attribute is modified.
Also override __delattr__
in case the attribute is deleted using del
.
class TestClass:
def __init__(self, a=None):
self.a = a
def _exec_a(self):
print(self.a)
def _exec_no_a(self):
print('no a')
def __setattr__(self, name, value):
# print('__setattr__():', name, value)
super().__setattr__(name, value)
if name == 'a':
if value is not None:
self._exec = self._exec_a
else:
del self.a
def __delattr__(self, name):
# print('__delattr__():', name)
super().__delattr__(name)
if name == 'a':
self._exec = self._exec_no_a
Use it like this:
>>> x = TestClass()
>>> x.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TestClass' object has no attribute 'a'
>>> x._exec()
no a
>>> x.a = 123
>>> x._exec()
123
>>> x.a = 'hello'
>>> x._exec()
hello
>>> x.a = None
>>> x.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'TestClass' object has no attribute 'a'
>>> x._exec()
no a
>>> x.a = 500
>>> x._exec()
500
>>> del x.a
>>> x._exec()
no a
>>> x.a = True
>>> x._exec()
True
>>> x = TestClass(a='xyz')
>>> x._exec()
xyz
>>> del x.a
>>> x._exec()
no a
Can't define method in class
To address the errors. Other than you can't define a method within a method.
Syntax error on token "String", new expected
Java syntax is looking for an object declaration like String s = new String()
.
Result cannot be resolved to a type
Result()
is not a defined as a method, so it is trying to be invoked, but can't.
Syntax error, insert ";" to complete Statement
String Result()
expects to be ended by a semi-colon.
Void methods cannot return a value
Self-explanatory, you can't do any more than return;
in a void
method, which main
is.
It would appear you meant to do this
import org.springframework.web.client.RestTemplate;
public class GetSurvey {
@Autowired
private RestTemplate restTemplate;
private static String getTemplate(String apiUrl) {
return restTemplate.getForObject(apiUrl,String.class);
}
public static void main(String[] args)
{
int SurveyID = 2107240;
String SurveyDate = "2016-01-07";
String SurveyType;
String apiurl = "https://restapi.surveygizmo.com/v4/survey/" + SurveyID + "...";
String result = getTemplate(apiurl);
}
}
Why does define_method not create a new class method in this example?
Use the Eigenclass
You can define the method as a class method using the eigenclass. For example:
module Helper
def translates(*attributes)
attributes.each do |attribute|
define_singleton_method("find_by_#{attribute}") do |value|
value
end
end
end
end
Related Topics
How to Wrap Link_To Around Some HTML Ruby Code
How to Get a Date from Date_Select or Select_Date in Rails
Rails Model, View, Controller, and Helper: What Goes Where
To Use Self. or Not.. in Rails
How to Use "Gets" and "Gets.Chomp" in Ruby
How to Format a Date in Ruby to Include "Rd" as in "3Rd"
Looking For Suggestions For Building a Secure Rest API Within Ruby on Rails
How to Distinguish Xlsx and Docx Files from Zip Archives
Error: Error Installing Ffi: Error: Failed to Build Gem Native Extension
Why Aren't Do/End and {} Always Equivalent
When Do I Need to Restart Server in Rails
Undefined Method Attr_Accessible
How to Add an Array to Another Array in Ruby and Not End Up With a Multi-Dimensional Result