I see the warning:
DEPRECATION WARNING: Base#after_update has been deprecated, please use Base.after_update :method instead. (called from <class:City> at /home/petrushka/webdev/my_app/app/models/city.rb:4)
What should I write instead of
def after_update
....
end
You should write as follow:
after_update :your_custom_method # macro-style
at least you can pass a block instead of a method:
after_update do |model|
model.name = model.name.capitalize unless model.name.blank?
end
more info here: http://guides.rails.info/active_record_validations_callbacks.html (choose rails edge documentation)
Related
I was trying to answer this question, and thought I could use the meta-object protocol to add attributes to a class. Here is a minimal example where I try to add an attribute test to the class Configuration after construction:
use v6;
class Configuration {
}
my $config = Configuration.new;
my $attr = Attribute.new(
:name('$.test'), # Trying to add a "test" attribute
:type(Str),
:has_accessor(1),
:package(Configuration)
);
$config.^add_attribute( $attr );
$config.^compose();
say "Current attributes: ", join ', ', $config.^attributes();
$attr.set_value( $config, "Hello" ); # <-- This fails with no such attribute '$.test'
say $config.test;
When I run this, I get:
Current attributes: $.test
P6opaque: no such attribute '$.test' on type Configuration in a Configuration when trying to bind a value
in block <unit> at ./p.p6 line 16
Attributes cannot be added after class composition time, which occurs at compile time when the closing } is reached when compiling the program. (This is the case for the P6opaque representation. It's not impossible that a representation could exist that allows this, but there's none specified at this time.)
Further to that, .^add_attribute is called on the meta-object, and for a class the attributes are per type, not per object; the code structure suggests that perhaps the expectation was per object. There's nothing that makes it impossible to have prototype object orientation (actually the MOP is designed so somebody could implement such an object system in Perl 6), but again there's nothing specified in Perl 6 itself that provides this.
Thus with the provided object system, such manipulation needs to be done at compile time, and before the closing }. That can be achieved as follows:
class Configuration {
BEGIN {
my $attr = Attribute.new(
:name('$!test'), # Trying to add a "test" attribute
:type(Str),
:has_accessor(1),
:package(Configuration)
);
Configuration.^add_attribute( $attr );
}
}
my $config = Configuration.new;
say "Current attributes: ", join ', ', $config.^attributes();
$config.^attributes[0].set_value( $config, "Hello" );
say $config.test;
This is one of the many places where Perl 6 is dynamic primarily by inviting the programmer to participate in compile time, rather than by making all things possible at runtime.
Finally, I'll note that there is a means to add attributes to an existing object, and on a per-object basis: by using does to mix a role in to it. That works by changing the type of the object along the way. There's some documentation on does here.
i'm trying to do something like this:
-- source file 1
my $queue = Thread::Queue->new();
MyModules::populateQueue(<pass $queue->enqueue method reference);
...
-- package file
package MyModules
sub populateQueue {
my $enqueue = $_[0];
my $item = <find item to add to queue>;
$enqueue->($item);
...
first, i'm not able to add "bless" to Thread::Queue
i've tried a couple of suggestions i found in stackoverflow:
my $enqueueRef = $queue->can('enqueue');
MyModules::populateQueue(\&enqueueRef); <--- fails in the package at line
$enqueue->($item) with undefined subroutine
MyModules::populateQueue(\&queue->enqueue) <-- same failure as above
any idea how to pass a method of an object as a parameter to a function that can then be used in the function?
Perl doesn't have a concept of a bound method reference. my $enqueue = $object->can('method') will return a code ref to a method if it exists, but the code ref isn't bound to that particular object – you still need to pass it as the first argument ($queue->$enqueue($item) or $enqueue->($queue, $item)).
To pass a bound method, the correct solution is to use an anonymous sub that wraps the method call:
populate_queue(sub { $queue->enqueue(#_) });
I'd like Scala compiler to show a deprecation warning whenever a particular function is found used. How can I achieve this?
I didn't notice the comment, kristian-domagala, so here is the example:
#deprecated("Reason this is old","01-08-2014")
def oldMethod = {
...
}
Annotate it as #deprecated.
I am rummaging through 7900+ lines of perl code. I needed to change a few things and things were going quite well even though i am just 36 hours into perl. I learned the basic constructs of the language and was able to get small things done. But then suddenly I have found a function call which does not have any definition anywhere. I grep'ed several times to check for all 'sub'. I could not find the functions definition. What am I missing ? Where is the definition of this function. I am quite sure this is a user defined function and not a library function(from its name i guessed this).
Please help me find this function's definition.
Here is a few lines from around the function usage.
(cfg_machine_isActive($ep)) {
staf_var_set($ep, VAR_PHASE, PHASE_PREP);
staf_var_set($ep, VAR_PREP, STATE_RUNNING);
} else {
cfg_machine_set_state($ep, STATE_FAILED);
}
}
$rc = rvt_deploy_library(); #this is the function that is the problem
dump_states() unless ($rc != 0);
Here is the answer:
(i could not post this an answer itself cos i dont have enough reputation)
I found that the fastest way to find the definition of an imported function in perl are the following commands:
>perl.exe -d <filename>.pl
This starts the debugger.
Then; do
b <name of the function/subroutine who's definition you are looking for>
in our case that would mean entering:
b rvt_deploy_library
next press 'c' to jump to the mentioned function/subroutine.
This brings the debugger to the required function. Now, you can see the line no. and location of the function/subroutine on the console.
main::rvt_deploy_library(D:/CAT/rvt/lib/rvt.pm:60):
There are a number of ways to declare a method in Perl. Here is an almost certainly incomplete list:
The standard way, eg. sub NAME { ... }
Using MooseX::Method::Signatures, method NAME (...) {...}
Assignment to a typeglob, eg. *NAME = sub {...};
In addition, if the package declares an AUTOLOAD function, then there may be no explicit definition of the method. See perlsub for more information.
You can inspect any perl value with the B module. In this case:
sub function_to_find {}
sub find_sub (\&) {
my $code = shift;
require B;
my $obj = B::svref_2object($code); # create a B::CV object from $code
print "$code:\n";
print " $$_[0]: $$_[1]\n" for
[file => $obj->FILE],
[line => $obj->GV->LINE],
[name => $obj->GV->NAME],
[package => $obj->STASH->NAME];
}
find_sub &function_to_find;
which prints something like:
CODE(0x80ff50):
file: so.pl
line: 7
name: function_to_find
package: main
B::Xref will show all functions declared in all the files used by your code.
I want to use a method of an object.
Like $myObject->helloWorld().
However there are a couple of methods so I loop through an array of method names and call the method like this:
my $methodName ="helloWorld";
$myObject->$methodNames;
This works quite nice but some objects don't have all methods.
How can I tell whether $myObject has a method called helloWorld or not?
You can use the UNIVERSAL::can method of all objects to determine what methods it supports:
if ($myObject->can($methodName)) {
$myObject->$methodName;
}
As Eric noted, you can usually use UNIVERSAL::can
It can be used either on an object as in your example ($obj->can($methodName)) or statically, on a class: (CLASS->can($methodName))
Please note that there are possible false negatives associated with using UNIVERSAL::can on objects/classes which have AUTOLOAD-ed methods - see the perldoc for details. So before using can() on an object/class, please be careful to verify that the class in question either does not use AUTOLOAD, or overrides can() to compensate, or uses forward declaration to compensate as described in can()'s perldoc - hat tip to brian d foy)
Also, please be careful to either ONLY call can() on actual objects, or encapsulate it in eval. It will die if called on a non-object (e.g. undef, scalar etc...)
The canonical way to use can is inside an eval block in case the thing that you have in your scalar variable isn't actually an object. You don't have to worry about that because you'll still get the right answer (a non-object or class can't respond to the method):
if( my $ref = eval { $obj->can( $method ) } ) {
$obj->$ref( #args );
}
The can has the added feature that it returns a code reference to the method. Sometimes that can be handy.
I used this method when checking database connections, passed into a function, such as
my $method = "ping";
if(defined ($local_dbh) && eval{ $local_dbh->can($method) } ) {
if ($local_dbh->ping) {
return $local_dbh;
}
}
else {
## do connection
...
}