[EP-tech] Re: Altering DajaObj/Eprint.pm behaviour without altering core code

Sebastien Francois sf2 at ecs.soton.ac.uk
Wed Apr 4 17:15:59 BST 2012


Hi John,

This wouldn't work (if I understand correctly what you're trying to do), 
because EPrints::DataObj::EPrint (any plugins/modules for that matter) 
exists only once in the entire "mod_perl" space so if something modifies 
a method's address (*EPrints::DataObj::EPrint::remove = \&something) 
this would affect anything running under mod_perl (so all the repositories).

In other words, you can't have two different versions of the same method 
running under the same process space.

What about you change your 'remove' method to have a local callback:

sub remove
{
...

#JLRS Added code
	if( $session->can_call( 'local_EPrints_DataObj_EPrint_remove' ) )
	{
		return $session->call( 'local_EPrints_DataObj_EPrint_remove', $self );
	}
#/JLRS Added code

	return $success;
}

# Then In a local file (ie archives/[id]/cfg/cfg.d/...):

$c->{local_EPrints_DataObj_EPrint_remove} = sub { # your code };


At least there you allow local callbacks (ie local behaviour), you know 
where your patch is (in perl_lib/...) and the change is kept minimal.

Seb.



On 04/04/12 16:44, John Salter wrote:
> For render_fileinfo Tim's suggestion would be OK, but what about non-rendering methods - like 'remove'?
> Currently in a modified ~/perl_lib/EPrints/DataObj/Eprint.pm, I have:
>
> sub remove
> {
> ...
>
> #JLRS Added code
>      my $repo = $self->{session}->get_repository->get_id;
>      if( $repo eq "sherpawhiterose" ){
> 	# some stuff that's only applicable to 'sherpawhiterose'
> 	...
>      }
> #/JLRS Added code
>
> 	return $success;
> }
>
> Ideally this would be done somewhere in ~/archives/sherpawhiterose/cfg/, and not affect any other archives.
> Could I wrap a set of rules with some kind of archive-specific selector:
> [in this archive]
> 	*EPrints::DataObj::EPrint::remove = \&patched_DataObj_EPrint_remove;
> 	*EPrints::DataObj::EPrint::move_to_archive = \&patched_DataObj_EPrint_move_to_archive;
> [/in this archive]
>
> Cheers,
> John
>
> -----Original Message-----
> From: eprints-tech-bounces at ecs.soton.ac.uk [mailto:eprints-tech-bounces at ecs.soton.ac.uk] On Behalf Of Sebastien Francois
> Sent: 04 April 2012 16:05
> To: eprints-tech at ecs.soton.ac.uk
> Subject: [EP-tech] Re: Altering DajaObj/Eprint.pm behaviour without altering core code
>
> On 04/04/12 15:49, John Salter wrote:
>> I really meant to suggest making the change in ~/archives/[ID]/cfg/cfg.d/core_overrides.pl
>>    - would a change in there result in this inheritance?
> I think it would since EPrints::DataObj::EPrint.pm is loaded once by the
> webserver and you're changing it.
>
> What about Tim Brody's suggestion? That would be rather clean.
>
> Alternatively, try something like that:
>
> *EPrints::DataObj::EPrint::render_fileinfo = \&patched_render_fileinfo;
>
>
> sub patched_render_fileinfo
> {
> 	my( $session, $field, $value, $alllangs, $nolink, $eprint ) = @_;
>
> 	if( $session->can_call( 'local_render_fileinfo' ) )
> 	{
> 		return $session->call( 'local_render_fileinfo', $session, $field, $value, $alllangs, $nolink, $eprint );
> 	}
>
> 	# original render_fileinfo code follows:
> 	# ...
> }
>
> $c->{local_render_fileinfo} = sub {
>
> 	# your custom code
>
> };
>
>
>
> If you don't define $c->{local_render_fileinfo} in your other
> repositories, then the original code will be executed.
>
> Seb.
>
>> I need to make the change in one archive only!
>>
>> Cheers,
>> John
>>
>> -----Original Message-----
>> From: eprints-tech-bounces at ecs.soton.ac.uk [mailto:eprints-tech-bounces at ecs.soton.ac.uk] On Behalf Of Sebastien Francois
>> Sent: 04 April 2012 15:41
>> To: eprints-tech at ecs.soton.ac.uk
>> Subject: [EP-tech] Re: Altering DajaObj/Eprint.pm behaviour without altering core code
>>
>> Good! Yes I'd add a file in cfg.d/ as you suggested. However be aware
>> that other repositories set up there (ie. archives/[id1],
>> archives/[id2]...) will inherit the change!
>>
>> Seb.
>>
>> On 04/04/12 15:33, John Salter wrote:
>>> Thanks Seb, works like a dream!
>>>
>>> Do you have any 'good practice' advice on how to do this within an archive?
>>> I already have ~/archives/[ID]/cfg/plugins/... for over-riding plugins.
>>> Would your advice be to add something within there, or to add something like cfg.d/core_overrides.pl?
>>>
>>> Cheers,
>>> John
>>>
>>> -----Original Message-----
>>> From: eprints-tech-bounces at ecs.soton.ac.uk [mailto:eprints-tech-bounces at ecs.soton.ac.uk] On Behalf Of Sebastien Francois
>>> Sent: 04 April 2012 12:29
>>> To: eprints-tech at ecs.soton.ac.uk
>>> Subject: [EP-tech] Re: Altering DajaObj/Eprint.pm behaviour without altering core code
>>>
>>> What about:
>>>
>>> *EPrints::DataObj::EPrint::render_fileinfo = \&my_render_fileinfo;
>>>
>>> sub my_render_fileinfo
>>> {
>>> # your code ...
>>> }
>>>
>>> Seb.
>>>
>>>
>>> On 04/04/12 12:18, John Salter wrote:
>>>> I'm trying to do something the 'right way'*.
>>>> This advice: http://wiki.eprints.org/w/Read_Only_Directories says I shouldn't be editing anything under eprints3/perl_lib/ (with a couple of exceptions).
>>>>
>>>> I need to alter the 'render_fileinfo' subroutine in ~/perl_lib/EPrints/DataObj/EPrint.pm.
>>>> How do I achieve this without:
>>>>      - altering the Eprint.pm file
>>>>      - ending up with some 'Subroutine render_fileinfo redefined' messages
>>>>      - using "no warnings 'redefine';" ;o)
>>>>
>>>> I've tried various attempts - without success.
>>>> I'm sure it can be done, and I'm sure it's a bit of perl magic I'm missing, and hopefully someone here can help!
>>>>
>>>> Cheers,
>>>> John



More information about the Eprints-tech mailing list