2013-07-18 21 views
9

Thứ nhất, đây là cách tôi gọi hàm:Làm thế nào để chọn một hàm .m cụ thể khi hai tồn tại?

eval([functionName '(''stringArg'')']); % functionName = 'someStringForTheFunctionName' 

Bây giờ, tôi có hai functionName chức năng trong con đường của tôi, một trong đó lấy và một stringArg khác mà có cái gì khác. Tôi nhận được một số lỗi bởi vì ngay bây giờ đầu tiên nó tìm thấy là chức năng mà không mất stringArg. Xem xét cách tôi gọi hàm functionName, làm cách nào để gọi hàm chính xác?

Edit:

Tôi đã thử các chức năng which:

which -all someStringForTheFunctionName 

Kết quả:

C:\........\x\someStringForTheFunctionName 
C:\........\y\someStringForTheFunctionName % Shadowed 

Chức năng shadowed là một tôi muốn gọi.

+1

câu hỏi liên quan: [Thực hiện một tập tin hoặc gọi một hàm có tập tin được đặt trong một thư mục khác với MATLAB?] (http://stackoverflow.com/questions/6153323/) –

+0

Darn bạn Eitan, bạn luôn tìm thấy câu trả lời như phút trước tôi haha gọi tốt mặc dù! – Shaun314

Trả lời

7

Tên chức năng phải là duy nhất trong MATLAB. Nếu không, vì vậy có các tên trùng lặp, sau đó MATLAB sử dụng tên đầu tiên mà nó tìm thấy trên đường dẫn tìm kiếm của bạn.

Có nói rằng, có một số tùy chọn mở cho bạn.

Tùy chọn 1. Sử dụng @ thư mục, đặt mỗi phiên bản vào một thư mục riêng biệt. Về cơ bản, bạn đang sử dụng khả năng của MATLAB để áp dụng một hàm cho các lớp cụ thể. Vì vậy, bạn có thể thiết lập một cặp thư mục:

@char 
@double 

Đặt bản sao của myfun.m trong các thư mục tương ứng. Bây giờ khi MATLAB nhìn thấy một đầu vào đôi để myfun, nó sẽ trực tiếp cuộc gọi đến phiên bản đôi. Khi MATLAB nhận được đầu vào char, nó đi vào phiên bản char.

CẨN THẬN. Không đặt các thư mục @ này một cách rõ ràng trên đường dẫn tìm kiếm của bạn. DO đặt chúng INSIDE một thư mục trên đường dẫn tìm kiếm của bạn. Một vấn đề với sơ đồ này là nếu bạn gọi hàm với đầu vào chính xác SINGLE, MATLAB có thể sẽ phù hợp, vì vậy bạn sẽ cần các phiên bản riêng biệt cho đơn, uint8, int8, int32, v.v. Bạn không thể chỉ có một phiên bản cho tất cả các loại số.

Tùy chọn 2. Chỉ có một phiên bản của hàm, kiểm tra đối số đầu tiên để xem nó là số hay char, sau đó các chi nhánh thực hiện một trong hai tác vụ khi thích hợp. Cả hai phần của mã sẽ đơn giản nhất là trong một tập tin sau đó. Lược đồ đơn giản sẽ có các hàm con hoặc các hàm lồng nhau để thực hiện công việc.

Tùy chọn 3. Đặt tên cho các hàm khác nhau. Hey, nó không phải là kết thúc của thế giới.

Tùy chọn 4: Theo Shaun chỉ ra, người ta chỉ có thể thay đổi thư mục hiện tại. MATLAB luôn trông đầu tiên trong thư mục hiện tại của bạn, vì vậy nó sẽ tìm thấy hàm trong thư mục đó khi cần thiết. Một vấn đề là đây là thời gian. Bất cứ khi nào bạn chạm vào một thư mục, mọi thứ sẽ chậm lại, bởi vì hiện tại có đầu vào đĩa cần thiết.

Phần tồi tệ nhất của việc thay đổi thư mục là cách bạn sử dụng MATLAB. Đó là (IMHO) một phong cách lập trình kém để buộc người dùng phải luôn ở trong một thư mục cụ thể dựa trên các mã đầu vào mà họ muốn chạy. Tốt hơn là một chương trình điều khiển dữ liệu. Nếu bạn sẽ đọc hoặc ghi dữ liệu, thì hãy nằm trong thư mục THAT.Sử dụng đường dẫn tìm kiếm MATLAB để phân loại tất cả các chức năng của bạn, vì các hàm có xu hướng không thay đổi nhiều. Đây là một cách làm việc sạch hơn nhiều so với yêu cầu người dùng di chuyển đến các thư mục cụ thể dựa trên cách họ sẽ gọi một hàm cụ thể.

Cá nhân, tôi có xu hướng đề xuất tùy chọn 2 là tốt nhất. Nó sạch sẽ. Nó chỉ có MỘT chức năng chính mà bạn cần phải làm việc. Nếu bạn muốn giữ lại khu chức năng, hãy đặt chúng thành các hàm lồng nhau hoặc phụ riêng biệt bên trong thân hàm chính. Bên trong tất nhiên, họ sẽ có tên riêng biệt, dựa trên cách họ được điều khiển.

+0

Hoặc, chỉ cần thay đổi thư mục trước khi bạn gọi nó và sau đó thay đổi lại sau khi được gọi. Không tạo tệp bổ sung, thay đổi tên hoặc đặt chức năng cùng nhau, tổng cộng hai dòng mã cơ bản hơn là tất cả những gì bạn cần. – Shaun314

0

EDIT: Câu trả lời cũ không còn tốt nữa

Lệnh chạy sẽ không hoạt động vì chức năng của nó, không phải tập lệnh. Thay vào đó, cách tiếp cận tốt nhất của bạn sẽ thành thật chỉ cần tìm ra chức năng nào cần chạy, tải thư mục hiện tại, thay đổi nó thành hàm của bạn, chạy nó, và sau đó thay đổi trở lại thư mục bắt đầu của bạn .

Cách tiếp cận này, trong khi không hoàn hảo, có vẻ như MUCH dễ viết mã hơn, dễ đọc hơn và ít bị phá vỡ hơn. Và nó không yêu cầu phải thay đổi tên hoặc tạo thêm tập tin hoặc chức năng xử lý.

+0

Có vẻ như nó chỉ dành cho 'Scripts' chứ không phải chức năng. –

+0

Ok yeah Tôi thấy rằng nó phải làm việc với các biến trong không gian làm việc của MATLAB, hmm, tôi đoán bạn có thể tạo một kịch bản lệnh bao bọc, nhưng điều đó sẽ đánh bại toàn bộ mục đích của câu hỏi này .. – Shaun314

+0

Có. Chạy chỉ áp dụng cho tập lệnh. Và các tập lệnh không thể chấp nhận đầu vào biến. –

2

OK, do đó, một câu trả lời lộn xộn, nhưng nó nên làm điều đó. Hàm kiểm tra của tôi là 'echo'

funcstr='echo'; % string representation of function 

Fs=which('-all',funcstr); 
for v=1:length(Fs) 
    if (strcmp(Fs{v}(end-1:end),'.m')) % Don''t move built-ins, they will be shadowed anyway 
     movefile(Fs{v},[Fs{v} '_BK']); 
    end 
end 
for v=1:length(Fs) 
    if (strcmp(Fs{v}(end-1:end),'.m')) 
     movefile([Fs{v} '_BK'],Fs{v}); 
    end 
    try 
     eval([funcstr '(''stringArg'')']); 
     break; 
    catch 
     if (strcmp(Fs{v}(end-1:end),'.m')) 
      movefile(Fs{v},[Fs{v} '_BK']); 
     end 
    end 
end 
for w=1:v 
    if (strcmp(Fs{v}(end-1:end),'.m')) 
     movefile([Fs{v} '_BK'],Fs{v}); 
    end 
end 
+0

Vì vậy, tôi có hai lựa chọn, thay đổi # 1 thư mục và quay trở lại thư mục ban đầu hoặC# 2 di chuyển tập tin vào thư mục hiện hành (thay đổi tên của nó) và di chuyển nó trở lại (thay đổi tên của nó trở lại)! –

1

Bạn cũng có thể tạo một hàm xử lý cho hàm được tô bóng. Vấn đề là hàm đầu tiên cao hơn trên đường dẫn MATLAB, nhưng bạn có thể phá vỡ nó bằng cách (tạm thời) thay đổi thư mục hiện tại.

Mặc dù nó không phải là tốt đẹp để thay đổi thư mục hiện tại (thực sự tôi không bao giờ thay đổi nó trong khi thực hiện mã), nó sẽ giải quyết vấn đề khá dễ dàng; đặc biệt nếu bạn sử dụng nó trong phần cấu hình của chức năng của bạn với một chức năng xử lý dai dẳng:

function outputpars = myMainExecFunction(inputpars) 
    % configuration 
    persistent shadowfun; 
    if isempty(shadowfun) 
     funpath1 = 'C:\........\x\fun'; 
     funpath2 = 'C:\........\y\fun'; % Shadowed 

     curcd = cd; 
     cd(funpath2); 
     shadowfun = @fun; 
     cd(curcd); % and go back to the original cd 
    end 

    outputpars{1} = shadowfun(inputpars); % will use the shadowed function 
    oupputpars{2} = fun(inputparts); % will use the function highest on the matlab path 
end 

Vấn đề này cũng đã được thảo luận here như một giải pháp khả thi để this problem.

Tôi tin rằng nó thực sự là cách duy nhất để quá tải một hàm dựng sẵn bên ngoài thư mục nguồn của hàm quá tải (ví dụ. Bạn muốn chạy của riêng bạn sum.m trong một thư mục khác hơn nơi bạn sum.m nằm.)

Các vấn đề liên quan